por - mutate_each/summaryise_each en dplyr: ¿cómo selecciono ciertas columnas y le doy nuevos nombres a las columnas mutadas?
filtros con dplyr (2)
Estoy un poco confundido sobre el verbo
mutate_each.
Es bastante sencillo usar la
mutate
básica para transformar una columna de datos en, por ejemplo, puntajes z, y crear una nueva columna en su data.frame (aquí con el nombre
z_score_data
):
newDF <- DF %>%
select(one_column) %>%
mutate(z_score_data = one_column - (mean(one_column) / sd(one_column))
Sin embargo, dado que tengo muchas columnas de datos que me gustaría transformar, parece que probablemente debería usar el verbo
mutate_each
.
newDF <- DF %>%
mutate_each(funs(scale))
Hasta aquí todo bien. Pero hasta el momento no he podido entender:
-
¿Cómo puedo dar nombres apropiados a estas nuevas columnas, como puedo
mutate
enmutate
? -
¿Cómo puedo seleccionar ciertas columnas que deseo mutar, como hice con
select
en el primer caso?
Gracias por tu ayuda.
Actualización para dplyr> = 0.4.3.9000
En la versión de desarrollo dplyr 0.4.3.9000 (en el momento de la redacción), los nombres dentro de
mutate_each
y
summarise_each
se han simplificado como se señala en las
News
:
El comportamiento de
summarise_each()
desummarise_each()
ymutate_each()
se ha modificado para que pueda forzar la inclusión de la función y el nombre de la variable:summarise_each(mtcars, funs(mean = mean), everything())
Esto es principalmente importante si desea aplicar solo 1 función dentro de
mutate_each
/
summarise_each
y desea dar a esas columnas nuevos nombres.
Para mostrar la diferencia, aquí está la salida de dplyr 0.4.3.9000 usando la nueva funcionalidad de nombres, en contraste con la opción a.2 a continuación:
library(dplyr) # >= 0.4.3.9000
iris %>% mutate_each(funs(mysum = sum(.)), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mysum Sepal.Width_mysum
#1 5.1 3.5 1.4 0.2 setosa 876.5 458.6
#2 4.9 3.0 1.4 0.2 setosa 876.5 458.6
#3 4.7 3.2 1.3 0.2 setosa 876.5 458.6
#4 4.6 3.1 1.5 0.2 setosa 876.5 458.6
#5 5.0 3.6 1.4 0.2 setosa 876.5 458.6
#6 5.4 3.9 1.7 0.4 setosa 876.5 458.6
# Petal.Length_mysum Petal.Width_mysum
#1 563.7 179.9
#2 563.7 179.9
#3 563.7 179.9
#4 563.7 179.9
#5 563.7 179.9
#6 563.7 179.9
Si no proporciona nuevos nombres y solo proporciona 1 función, dplyr cambiará las columnas existentes (como lo hizo en versiones anteriores):
iris %>% mutate_each(funs(sum), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 876.5 458.6 563.7 179.9 setosa
#2 876.5 458.6 563.7 179.9 setosa
#3 876.5 458.6 563.7 179.9 setosa
#4 876.5 458.6 563.7 179.9 setosa
#5 876.5 458.6 563.7 179.9 setosa
#6 876.5 458.6 563.7 179.9 setosa
Supongo que esta nueva funcionalidad estará disponible a través de CRAN en la próxima versión de lanzamiento 0.4.4.
dplyr verions <= 0.4.3:
¿Cómo puedo dar nombres apropiados a estas nuevas columnas, como puedo hacerlo en mutación?
a) 1 función aplicada en
mutate_each
/
summarise_each
Si aplica solo 1 función dentro de
mutate_each
o
summarise_each
, las columnas existentes se transformarán y los nombres se conservarán como solían ser, a
menos que proporcione un vector con nombre a
mutate_each_
/
summarise_each_
(consulte la opción a.4)
Aquí hay unos ejemplos:
a.1 solo 1 función -> mantendrá los nombres existentes
iris %>% mutate_each(funs(sum), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 876 459 564 180 setosa
#2 876 459 564 180 setosa
#3 876 459 564 180 setosa
#4 876 459 564 180 setosa
#5 876 459 564 180 setosa
#6 876 459 564 180 setosa
a.2 también si especifica una nueva extensión de nombre de columna:
iris %>% mutate_each(funs(mysum = sum(.)), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 876 459 564 180 setosa
#2 876 459 564 180 setosa
#3 876 459 564 180 setosa
#4 876 459 564 180 setosa
#5 876 459 564 180 setosa
#6 876 459 564 180 setosa
a.3 Especifique manualmente un nuevo nombre por columna (pero solo práctico para pocas columnas):
iris %>% mutate_each(funs(sum), SLsum = Sepal.Length,SWsum = Sepal.Width, -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species SLsum SWsum
#1 5.1 3.5 1.4 0.2 setosa 876 459
#2 4.9 3.0 1.4 0.2 setosa 876 459
#3 4.7 3.2 1.3 0.2 setosa 876 459
#4 4.6 3.1 1.5 0.2 setosa 876 459
#5 5.0 3.6 1.4 0.2 setosa 876 459
#6 5.4 3.9 1.7 0.4 setosa 876 459
a.4 Use un vector con nombre para crear columnas adicionales con nuevos nombres:
caso 1: mantener columnas originales
A diferencia de las opciones a.1, a.2 y a.3, dplyr mantendrá las columnas existentes sin cambios y creará nuevas columnas en este enfoque.
Los nombres de las nuevas columnas son iguales a los nombres del vector nombrado que crea de antemano (en este caso,
vars
).
vars <- names(iris)[1:2] # choose which columns should be mutated
vars <- setNames(vars, paste0(vars, "_sum")) # create new column names
iris %>% mutate_each_(funs(sum), vars) %>% head
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum
#1 5.1 3.5 1.4 0.2 setosa 876.5 458.6
#2 4.9 3.0 1.4 0.2 setosa 876.5 458.6
#3 4.7 3.2 1.3 0.2 setosa 876.5 458.6
#4 4.6 3.1 1.5 0.2 setosa 876.5 458.6
#5 5.0 3.6 1.4 0.2 setosa 876.5 458.6
#6 5.4 3.9 1.7 0.4 setosa 876.5 458.6
caso 2: eliminar columnas originales
Como puede ver, este enfoque mantiene las columnas existentes sin cambios y agrega nuevas columnas con nombres específicos.
En caso de que no desee conservar las columnas originales, pero solo las columnas recién creadas (y las otras columnas), puede agregar una declaración de
select
después:
iris %>% mutate_each_(funs(sum), vars) %>% select(-one_of(vars)) %>% head
# Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum
#1 1.4 0.2 setosa 876.5 458.6
#2 1.4 0.2 setosa 876.5 458.6
#3 1.3 0.2 setosa 876.5 458.6
#4 1.5 0.2 setosa 876.5 458.6
#5 1.4 0.2 setosa 876.5 458.6
#6 1.7 0.4 setosa 876.5 458.6
b) más de 1 función aplicada en
mutate_each
/
summarise_each
b.1 Deje que dplyr descubra nuevos nombres
Si aplicó más de 1 función, puede dejar que dplyr descubra los nombres por sí mismo (y mantendrá las columnas existentes):
iris %>% mutate_each(funs(sum, mean), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum Petal.Length_sum
#1 5.1 3.5 1.4 0.2 setosa 876 459 564
#2 4.9 3.0 1.4 0.2 setosa 876 459 564
#3 4.7 3.2 1.3 0.2 setosa 876 459 564
#4 4.6 3.1 1.5 0.2 setosa 876 459 564
#5 5.0 3.6 1.4 0.2 setosa 876 459 564
#6 5.4 3.9 1.7 0.4 setosa 876 459 564
# Petal.Width_sum Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
#1 180 5.84 3.06 3.76 1.2
#2 180 5.84 3.06 3.76 1.2
#3 180 5.84 3.06 3.76 1.2
#4 180 5.84 3.06 3.76 1.2
#5 180 5.84 3.06 3.76 1.2
#6 180 5.84 3.06 3.76 1.2
b.2 Especifique manualmente nuevos nombres de columna
Otra opción, cuando se usa más de 1 función, es especificar la extensión del nombre de la columna por su cuenta:
iris %>% mutate_each(funs(MySum = sum(.), MyMean = mean(.)), -Species) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_MySum Sepal.Width_MySum Petal.Length_MySum
#1 5.1 3.5 1.4 0.2 setosa 876 459 564
#2 4.9 3.0 1.4 0.2 setosa 876 459 564
#3 4.7 3.2 1.3 0.2 setosa 876 459 564
#4 4.6 3.1 1.5 0.2 setosa 876 459 564
#5 5.0 3.6 1.4 0.2 setosa 876 459 564
#6 5.4 3.9 1.7 0.4 setosa 876 459 564
# Petal.Width_MySum Sepal.Length_MyMean Sepal.Width_MyMean Petal.Length_MyMean Petal.Width_MyMean
#1 180 5.84 3.06 3.76 1.2
#2 180 5.84 3.06 3.76 1.2
#3 180 5.84 3.06 3.76 1.2
#4 180 5.84 3.06 3.76 1.2
#5 180 5.84 3.06 3.76 1.2
#6 180 5.84 3.06 3.76 1.2
¿Cómo puedo seleccionar ciertas columnas que deseo mutar, como hice con select en el primer caso?
Puede hacerlo haciendo referencia a las columnas que se mutarán (o dejarán fuera) dando sus nombres como aquí (mutate Sepal.Length, pero no Species):
iris %>% mutate_each(funs(sum), Sepal.Length, -Species) %>% head()
Además, puede usar funciones especiales para seleccionar columnas que se mutarán, todas las columnas que comienzan con o contienen una palabra determinada, etc., por ejemplo:
iris %>% mutate_each(funs(sum), contains("Sepal"), -Species) %>% head()
Para obtener más información sobre esas funciones, consulte
?mutate_each
y
?select
?mutate_each
.
Editar 1 después del comentario:
Si desea utilizar la evaluación estándar, dplyr proporciona versiones SE de la mayoría de las funciones que terminan con un "_" adicional. Entonces en este caso usarías:
x <- c("Sepal.Width", "Sepal.Length") # vector of column names
iris %>% mutate_each_(funs(sum), x) %>% head()
Observe el
mutate_each_
que usé aquí.
Edición 2: actualizado con la opción a.4
mutate_each
quedará en desuso, considere usar
mutate_at
.
De la documentación de
dplyr_0.5.0
:
En el futuro, mutate_each () y summaryise_each () quedarán en desuso en favor de una familia de funciones más característica: mutate_all (), mutate_at (), mutate_if (), summaryise_all (), summaryise_at () y summaryise_if ().
Aplique una función a todas las variables excepto las
Species
:
Advertencia: el parámetro ''.cols'' está en desuso, ¡vea la nota al final!
iris %>% mutate_at(.cols=vars(-Species), .funs=funs(mysum = sum(.))) %>% head()
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mysum Sepal.Width_mysum
1 5.1 3.5 1.4 0.2 setosa 876.5 458.6
2 4.9 3.0 1.4 0.2 setosa 876.5 458.6
3 4.7 3.2 1.3 0.2 setosa 876.5 458.6
4 4.6 3.1 1.5 0.2 setosa 876.5 458.6
5 5.0 3.6 1.4 0.2 setosa 876.5 458.6
6 5.4 3.9 1.7 0.4 setosa 876.5 458.6
Petal.Length_mysum Petal.Width_mysum
1 563.7 179.9
2 563.7 179.9
3 563.7 179.9
4 563.7 179.9
5 563.7 179.9
6 563.7 179.9
Aplicar una función a un subconjunto de variables
vars_to_process=c("Petal.Length","Petal.Width")
iris %>% mutate_at(.cols=vars_to_process, .funs=funs(mysum = sum(.))) %>% head()
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Petal.Length_mysum Petal.Width_mysum
1 5.1 3.5 1.4 0.2 setosa 563.7 179.9
2 4.9 3.0 1.4 0.2 setosa 563.7 179.9
3 4.7 3.2 1.3 0.2 setosa 563.7 179.9
4 4.6 3.1 1.5 0.2 setosa 563.7 179.9
5 5.0 3.6 1.4 0.2 setosa 563.7 179.9
6 5.4 3.9 1.7 0.4 setosa 563.7 179.9
¡Actualizar! para la versión dplyr 0.7.1 (2017-08-08)
Si ves el mensaje:
.cols
ha cambiado de nombre y está en desuso, utilice.vars
luego cambie
.cols
por
.vars
.
iris %>% mutate_at(.vars=vars(-Species), .funs=funs(mysum = sum(.))) %>% head()
Otro ejemplo:
iris %>% mutate_at(.vars=vars(Sepal.Width), .funs=funs(mysum = sum(.))) %>% head()
Es equivalente a:
iris %>% mutate_at(.vars=vars("Sepal.Width"), .funs=funs(mysum = sum(.))) %>% head()
Además, en esta versión,
mutate_each
está en desuso:
mutate_each()
está en desuso. Utilicemutate_all()
,mutate_at()
omutate_if()
lugar. Para mapearfuns
sobre una selección de variables, usemutate_at()