mutate ifelse funcion cheatsheet r dplyr

ifelse - dplyr sin codificar los nombres de las variables



funcion mutate en r (3)

El gran Hadley Wickham mismo (¡santificado sea su nombre!) Sugirió this en los mutatr Google mutatr :

d <- expand.grid(1:3, 20:22) my.variable <- ''Var1'' percent_rank <- function(x) rank(x)/max(rank(x)) call <- substitute(mutate(d, percent_rank(var)), list(var = as.name(my.variable))) eval(call) # Var1 Var2 percent_rank(Var1) # 1 1 20 0.250 # 2 2 20 0.625 # 3 3 20 1.000 # 4 1 21 0.250 # 5 2 21 0.625 # 6 3 21 1.000 # 7 1 22 0.250 # 8 2 22 0.625 # 9 3 22 1.000

¿Es posible usar la función de mutar de dplyr sin codificar los nombres de las variables? Por ejemplo, el siguiente código funciona, porque codifiqué el nombre Var1:

> d=expand.grid(1:3, 20:22) > d Var1 Var2 1 1 20 2 2 20 3 3 20 4 1 21 5 2 21 6 3 21 7 1 22 8 2 22 9 3 22 > d=mutate(d, x=percent_rank(Var1)) > d Var1 Var2 x 1 1 20 0.000 2 2 20 0.375 3 3 20 0.750 4 1 21 0.000 5 2 21 0.375 6 3 21 0.750 7 1 22 0.000 8 2 22 0.375 9 3 22 0.750

Sin embargo, cuando hago que el nombre de la variable sea una variable, ya no funciona:

> my.variable=''Var1'' > d=mutate(d, x=percent_rank(my.variable)) > d Var1 Var2 x 1 1 20 NaN 2 2 20 NaN 3 3 20 NaN 4 1 21 NaN 5 2 21 NaN 6 3 21 NaN 7 1 22 NaN 8 2 22 NaN 9 3 22 NaN

Las funciones eval () y as.symbol () tampoco parecen ayudar.


En la versión de desarrollo de dplyr (a la espera de la nueva versión 0.6.0 ), con la introducción de quosures y funciones quosures ( !! , UQ ) para evaluar las citas en group_by/summarise/mutate , esto se vuelve más fácil.

my.variable <- quo(Var1) percent_rank <- function(x) rank(x)/max(rank(x)) d %>% mutate(x = percent_rank(!!my.variable)) # Var1 Var2 x #1 1 20 0.250 #2 2 20 0.625 #3 3 20 1.000 #4 1 21 0.250 #5 2 21 0.625 #6 3 21 1.000 #7 1 22 0.250 #8 2 22 0.625 #9 3 22 1.000

También tiene otras características para pasar nombres de columna.

mynewvar <- ''x'' d %>% mutate(!!mynewvar := percent_rank(!!my.variable)) # Var1 Var2 x #1 1 20 0.250 #2 2 20 0.625 #3 3 20 1.000 #4 1 21 0.250 #5 2 21 0.625 #6 3 21 1.000 #7 1 22 0.250 #8 2 22 0.625 #9 3 22 1.000

También podemos crear una función y pasar el argumento.

f1 <- function(dat, myvar, colN){ myvar <- enquo(myvar) colN <- quo_name(enquo(colN)) dat %>% mutate(!!colN := percent_rank(!!myvar)) } f1(d, Var1, x) # Var1 Var2 x #1 1 20 0.250 #2 2 20 0.625 #3 3 20 1.000 #4 1 21 0.250 #5 2 21 0.625 #6 3 21 1.000 #7 1 22 0.250 #8 2 22 0.625 #9 3 22 1.000

En la función anterior, enquo hace la funcionalidad similar como substitute de la base R al tomar los argumentos de entrada del usuario y convertirlos en quosure . Como necesitamos el nombre de la columna en la cadena, podemos usar quo_name para hacer la conversión a la cadena y la evaluación dentro de la llamada de mutate se realiza sin citar ( !! o UQ )

datos

d <- expand.grid(1:3, 20:22)


Puede usar get y precisar el entorno en el que se encuentra el objeto "Var1".

> my.variable = ''Var1'' > mutate(d, x = percent_rank(get(my.variable, envir = as.environment(d)))) Var1 Var2 x 1 1 20 0.000 2 2 20 0.375 3 3 20 0.750 4 1 21 0.000 5 2 21 0.375 6 3 21 0.750 7 1 22 0.000 8 2 22 0.375 9 3 22 0.750

Le sugiero que lea más sobre la "evaluación no estándar" en el wiki de "Programación avanzada R" de Hadley Wickham: http://adv-r.had.co.nz/Computing-on-the-language.html

EDITAR

Esta respuesta fue votada recientemente, así que me di cuenta de que la solución que di hace un año y medio no era realmente buena y aprovecho esta oportunidad para actualizar mi respuesta.

Desde dplyr 0.3 puede usar la versión de evaluación estándar de las funciones de dplyr, usando sus versiones "fun_".

También tiene que usar interp from the lazyeval package si está haciendo algunos cálculos sobre las variables:

my.variable = "Var1" expr <- lazyeval::interp(~percent_rank(x), x = as.name(my.variable)) mutate_(d, .dots = setNames(list(expr), "x")) Var1 Var2 x 1 1 20 0.000 2 2 20 0.375 3 3 20 0.750 4 1 21 0.000 5 2 21 0.375 6 3 21 0.750 7 1 22 0.000 8 2 22 0.375 9 3 22 0.750