vectores tablas seleccionar funciones filas eliminar data contar concatenar columnas r

seleccionar - tablas en r



¿Cómo se codifica una función R para que ''sepa'' buscar en ''datos'' las variables en otros argumentos? (3)

Así es como codificaría myfun() :

myfun <- function(a, b, data) { eval(substitute(a + b), envir=data, enclos=parent.frame()) } myfun(mpg, hp, mtcars) # [1] 131.0 131.0 115.8 131.4 193.7 123.1 259.3 86.4 117.8 142.2 140.8 196.4 # [13] 197.3 195.2 215.4 225.4 244.7 98.4 82.4 98.9 118.5 165.5 165.2 258.3 # [25] 194.2 93.3 117.0 143.4 279.8 194.7 350.0 130.4

Si está familiarizado con with() , es interesante ver que funciona casi exactamente de la misma manera:

> with.default # function (data, expr, ...) # eval(substitute(expr), data, enclos = parent.frame()) # <bytecode: 0x016c3914> # <environment: namespace:base>

En ambos casos, la idea clave es crear primero una expresión a partir de los símbolos pasados ​​como argumentos y luego evaluar esa expresión utilizando data como el "entorno" de la evaluación.

La primera parte (por ejemplo, convertir a + b en la expresión mpg + hp ) es posible gracias a substitute() . La segunda parte es posible porque eval() fue bellamente diseñado, de modo que puede tomar un data.frame como su entorno de evaluación.

Si tu corres:

mod <- lm(mpg ~ factor(cyl), data=mtcars)

Se ejecuta, porque lm sabe buscar en mtcars para encontrar mpg y cyl.

Sin embargo, la mean(mpg) falla porque no puede encontrar mpg, así que sí mean(mtcars$mpg) .

¿Cómo se codifica una función para que sepa buscar las variables en ''datos''?

myfun <- function (a,b,data){ return(a+b) }

Esto funcionará con:

myfun(mtcars$mpg, mtcars$hp)

pero fallará con:

myfun(mpg,hp, data=mtcars )

Aclamaciones


Esto no es exactamente como lo que pediste, pero si no conoces with() esta podría ser una opción:

myfun <- function (a,b){ return(a+b) } with(mtcars, myfun(mpg, hp))

Puede eliminar el argumento de data a myfun para esto.


lm "sabe" que buscar en su argumento de data porque en realidad construye una llamada a model.frame usando su propia llamada como base. Si observa el código de lm , verá la maquinaria necesaria en la primera docena de líneas aproximadamente.

Podría replicar esto para sus propios fines, pero si sus necesidades son más simples, no tiene que ir a la misma medida. Por ejemplo:

myfun <- function(..., data) eval(match.call(expand.dots=FALSE)$...[[1]], data)

O simplemente mira evalq .