vacio - recodificar variables en r




Pasando un nombre de variable a una función en R (2)

Me he dado cuenta de que muchos paquetes le permiten pasar nombres de símbolos que pueden no ser válidos en el contexto donde se llama a la función. Me pregunto cómo funciona esto y cómo puedo usarlo en mi propio código.

Aquí hay un ejemplo con ggplot2:

a <- data.frame(x=1:10,y=1:10)
library(ggplot2)
qplot(data=a,x=x,y=y)

x e y no existen en mi espacio de nombres, pero ggplot entiende que son parte del marco de datos y pospone su evaluación a un contexto en el que son válidos. He intentado hacer lo mismo:

b <- function(data,name) { within(data,print(name)) }
b(a,x)

Sin embargo, esto falla miserablemente:

Error in print(name) : object 'x' not found

¿Qué estoy haciendo mal? ¿Como funciona esto?

Nota : esto no es un duplicado del nombre de la variable Pasar a una función en r


Puedes hacer esto usando match.call por ejemplo:

b <-  function(data,name) {

  ## match.call return a call containing the specified arguments 
  ## and the function name also 
  ## I convert it to a list , from which I remove the first element(-1)
  ## which is the function name

  pars <- as.list(match.call()[-1])
  data[,as.character(pars$name)]

}

 b(mtcars,cyl)
 [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4

explicación:

match.call devuelve una llamada en la que todos los argumentos especificados se especifican por sus nombres completos.

Así que aquí la salida de match.call es de 2 símbolos:

b <-  function(data,name) {
  str(as.list(match.call()[-1]))  ## I am using str to get the type and name
}

b(mtcars,cyl)
List of 2
 $ data: symbol mtcars
 $ name: symbol cyl

Entonces utilizo el primer símbolo mtcars y convierto el segundo a una cadena:

mtcars[,"cyl"]

o equivalente a:

eval(pars$data)[,as.character(pars$name)]

Sé que este es un hilo más antiguo, pero es uno al que me he referido en el pasado. Recientemente he descubierto lo que creo que es un mejor enfoque para pasar nombres de variables. Así que pensé en incluirlo. Espero que esto ayude a alguien.

a <- data.frame(x = 1:10, y = 1:10)

b <- function(df, name){
    eval(substitute(name), df)
}

b(a, x)
  [1]  1  2  3  4  5  6  7  8  9 10

Actualización El enfoque utiliza una evaluación no estándar. Comencé a explicar pero rápidamente me di cuenta de que Hadley Wickham lo hace mucho mejor que yo. Lea este http://adv-r.had.co.nz/Computing-on-the-language.html







lazy-evaluation