when studio mutate case_when r dplyr

r - studio - caso_cuando en tubo de mutación



r studio case when (6)

Parece que dplyr::case_when no se comporta como otros comandos en una llamada dplyr::mutate . Por ejemplo:

library(dplyr) case_when(mtcars$carb <= 2 ~ "low", mtcars$carb > 2 ~ "high") %>% table

trabajos:

. high low 15 17

Pero ponga case_when en una cadena de mutate :

mtcars %>% mutate(cg = case_when(carb <= 2 ~ "low", carb > 2 ~ "high"))

y obtienes:

Error: object ''carb'' not found

mientras esto funciona bien

mtcars %>% mutate(cg = carb %>% cut(c(0, 2, 8)))


A partir de la versión 0.7.0 de dplyr , case_when funciona dentro de case_when siguiente manera:

library(dplyr) # >= 0.7.0 mtcars %>% mutate(cg = case_when(carb <= 2 ~ "low", carb > 2 ~ "high"))

Para más información: http://dplyr.tidyverse.org/reference/case_when.html


Además de la respuesta de @ akrun anterior, tenga en cuenta que el paréntesis de cierre para el case_when() no se puede colocar en su propia línea.

Por ejemplo, esto funciona bien:

mtcars %>% mutate(cg = case_when( .$carb <= 2 ~ "low", .$carb > 2 ~ "high"))

pero esto no:

mtcars %>% mutate(cg = case_when( .$carb <= 2 ~ "low", .$carb > 2 ~ "high") )


En mi caso, la cuasiquotación ayudó mucho. Puede crear de antemano un conjunto de fórmulas citadas que definen las reglas de mutación (y usar nombres de columna conocidos como en la primera fórmula o beneficiarse de !! y crear reglas dinámicamente como en la segunda fórmula), que luego se utiliza dentro de mutate - case_when combinación como aquí

library(dplyr) library(rlang) pattern <- quos(gear == 3L ~ "three", !!sym("gear") == 4L ~ "four", gear == 5L ~ "five") # Or # pattern <- list( # quo(gear == 3L ~ "three"), # quo(!!sym("gear") == 4L ~ "four"), # quo(gear == 5L ~ "five")) # mtcars %>% mutate(test = case_when(!!!pattern)) %>% head(10L) #> mpg cyl disp hp drat wt qsec vs am gear carb test #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 four #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 four #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 four #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 three #> 5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 three #> 6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 three #> 7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 three #> 8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 four #> 9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 four #> 10 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 four

Prefiero tal solución porque permite crear reglas complejas, por ejemplo, usando map2 con condiciones LHS y valores RHS para generar fórmulas citadas

library(rlang) library(purrr) map2(c(3, 4, 5), c("three", "four", "five"), ~quo(gear == !!.x ~ !!.y)) #> [[1]] #> <quosure> #> expr: ^gear == 3 ~ "three" #> env: 0000000014286520 #> #> [[2]] #> <quosure> #> expr: ^gear == 4 ~ "four" #> env: 000000001273D0E0 #> #> [[3]] #> <quosure> #> expr: ^gear == 5 ~ "five" #> env: 00000000125870E0

y usarlo en diferentes lugares, aplicar a diferentes conjuntos de datos sin la necesidad de escribir manualmente todas las reglas cada vez que necesite una mutación compleja.

Como respuesta final al problema, 7 símbolos adicionales y dos paréntesis lo resuelven

library(rlang) library(dplyr) mtcars %>% mutate(test = case_when(!!!quos(gear == 3L ~ "three", gear != 3L ~ "not three"))) %>% head(10L) #> mpg cyl disp hp drat wt qsec vs am gear carb test #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 not three #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 not three #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 not three #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 three #> 5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 three #> 6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 three #> 7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 three #> 8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 not three #> 9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 not three #> 10 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 not three

Creado el 16/01/2019 por el paquete reprex (v0.2.1.9000)


Gracias a @sumedh: @hadley here que esta es una deficiencia conocida de case_when :

case_when() todavía es algo experimental y actualmente no funciona dentro de mutate() . Eso se solucionará en una versión futura.


Podemos usar .$

mtcars %>% mutate(cg = case_when(.$carb <= 2 ~ "low", .$carb > 2 ~ "high")) %>% .$cg %>% table() # high low # 15 17


biblioteca (dplyr) # cargando el paquete dplyr

content150_fortified <- content150 %>% #creating a new variable mutate(number_yn = case_when( #creating a new column using mutate number >= 18 & number <=25 ~ "no", # if number is "none", make number_yn "no" number!="none" ~ "yes" # if number is not "none", make number_yn "yes" ) )