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 demutate()
. 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"
)
)