usar sheet mutate meaning como cheat r dplyr

sheet - tidyr r



Combinar mutar con valores condicionales. (3)

Con dplyr 0.7.2 , puede usar la muy útil función case_when :

x=read.table( text="V1 V2 V3 V4 1 1 2 3 5 2 2 4 4 1 3 1 4 1 1 4 4 5 1 3 5 5 5 5 4") x$V5 = case_when(x$V1==1 & x$V2!=4 ~ 1, x$V2==4 & x$V3!=1 ~ 2, TRUE ~ 0)

Tenga en cuenta que las NA no son tratadas especialmente, ya que puede ser engañosa. La función devolverá NA solo cuando no se cumpla ninguna condición. Si coloca una línea con TRUE ~ ... , como hice en mi ejemplo, el valor de retorno nunca será NA .

case_when indicar case_when a case_when que coloque NA donde corresponda agregando una declaración como is.na(x$V1) | is.na(x$V3) ~ NA_integer_ is.na(x$V1) | is.na(x$V3) ~ NA_integer_ . Consejo: ¡la función dplyr::coalesce() puede ser realmente útil aquí algunas veces!

Además, NA solo no funcionará, tienes que poner valores especiales de NA : NA_integer_ , NA_character_ o NA_real_ .

En un marco de datos grande ("myfile") con cuatro columnas, tengo que agregar una quinta columna con valores conditonalmente basados ​​en las primeras cuatro columnas. Recientemente me he convertido en un gran fan de dplyr, principalmente debido a su velocidad en grandes conjuntos de datos. Así que me preguntaba si podría resolver mi problema utilizando la función de mutar.

Mi marco de datos (en realidad, una versión más corta) se parece a esto:

V1 V2 V3 V4 1 1 2 3 5 2 2 4 4 1 3 1 4 1 1 4 4 5 1 3 5 5 5 5 4

Los valores de la quinta columna (V5) se basan en algunas reglas condicionales:

if (V1==1 & V2!=4){ V5 <- 1 } else if (V2==4 & V3!=1){ V5 <- 2 } else { V5 <- 0 }

Ahora quiero usar la función de mutar para usar estas reglas en todas las filas (por lo que no tengo que usar un ciclo lento). Algo como esto (y sí, sé que no funciona de esta manera):

myfile <- mutate(myfile, if (V1==1 & V2!=4){V5 = 1} else if (V2==4 & V3!=1){V5 = 2} else {V5 = 0})

Este debería ser el resultado:

V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0

¿Cómo hacer esto en dplyr ?


Parece que el derivedFactor derivado del paquete de mosaic fue diseñado para esto. En este ejemplo, se vería algo así como:

library(mosaic) myfile <- mutate(myfile, V5 = derivedFactor( "1" = (V1==1 & V2!=4), "2" = (V2==4 & V3!=1), .method = "first", .default = 0 ))

(Si desea que el resultado sea numérico en lugar de un factor, envuelva el derivedFactor con un as.numeric ).

Tenga en cuenta que la opción .default combinada con .method = "first" establece la condición "else"; este enfoque se describe en el archivo de ayuda para el derivedFactor .


Prueba esto:

myfile %>% mutate(V5 = (V1 == 1 & V2 != 4) + 2 * (V2 == 4 & V3 != 1))

dando:

V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0

o esto:

myfile %>% mutate(V5 = ifelse(V1 == 1 & V2 != 4, 1, ifelse(V2 == 4 & V3 != 1, 2, 0)))

dando:

V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0

Te sugiero que obtengas un nombre mejor para tu marco de datos. myfile hace que parezca que tiene un nombre de archivo.

Anteriormente usé esta entrada:

myfile <- structure(list(V1 = c(1L, 2L, 1L, 4L, 5L), V2 = c(2L, 4L, 4L, 5L, 5L), V3 = c(3L, 4L, 1L, 1L, 5L), V4 = c(5L, 1L, 1L, 3L, 4L )), .Names = c("V1", "V2", "V3", "V4"), class = "data.frame", row.names = c("1", "2", "3", "4", "5"))

Actualización 1 Desde que se publicó originalmente, dplyr ha cambiado %.% %>% así que modifiqué la respuesta en consecuencia.

La actualización 2 dplyr ahora tiene case_when que proporciona otra solución:

myfile %>% mutate(V5 = case_when(V1 == 1 & V2 != 4 ~ 1, V2 == 4 & V3 != 1 ~ 2, TRUE ~ 0))