mutate_each / summarise_each в dplyr: как выбрать определенные столбцы и дать новые имена измененным столбцам?
Я немного смущен dplyr
глагол mutate_each.
Это довольно просто использовать основные mutate
преобразовать столбец данных, скажем, в z-показатели, и создать новый столбец в вашем data.frame (здесь с именем z_score_data
):
newDF <- DF %>%
select(one_column) %>%
mutate(z_score_data = one_column - (mean(one_column) / sd(one_column))
Однако, поскольку у меня есть много столбцов данных, которые я хотел бы преобразовать, похоже, мне, вероятно, следует использовать mutate_each
глагол.
newDF <- DF %>%
mutate_each(funs(scale))
Все идет нормально. Но пока я не смог понять:
- Как я могу дать этим новым столбцам соответствующие имена, как я могу в
mutate
? - Как я могу выбрать определенные столбцы, которые я хочу изменить, как я сделал с
select
в первом случае?
Спасибо за вашу помощь.
2 ответа
Обновление для dplyr >= 0.4.3.9000
В версии разработки dplyr 0.4.3.9000 (на момент написания), именование внутри mutate_each
а также summarise_each
был упрощен, как отмечено в новостях:
Поведение именования
summarise_each()
а такжеmutate_each()
был изменен, так что вы можете принудительно включить как функцию, так и имя переменной:summarise_each(mtcars, funs(mean = mean), everything())
Это особенно важно, если вы хотите применить только 1 функцию внутри mutate_each
/ summarise_each
и вы хотите дать этим столбцам новые имена.
Чтобы показать разницу, вот вывод dplyr 0.4.3.9000 с использованием новой функциональности именования, в отличие от опции a.2 ниже:
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
Если вы не предоставляете новые имена и только одну функцию, dplyr изменит существующие столбцы (как это было в предыдущих версиях):
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
Я предполагаю, что эта новая функциональность будет доступна через CRAN в следующей версии 0.4.4.
dplyr verions <= 0.4.3:
Как я могу дать этим новым столбцам соответствующие имена, как я могу в mutate?
а) 1 функция применяется в mutate_each
/ summarise_each
Если вы применяете только 1 функцию внутри mutate_each
или же summarise_each
существующие столбцы будут преобразованы, а имена будут сохранены в прежнем виде, если только вы не укажете именованный вектор для mutate_each_
/ summarise_each_
(см. вариант а.4)
Вот некоторые примеры:
a.1 только 1 функция -> сохранит существующие имена
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
а.2 также, если вы укажете новое расширение имени столбца:
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
а.3 Вручную указать новое имя для каждого столбца (но только для нескольких столбцов):
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
а.4 Используйте именованный вектор для создания дополнительных столбцов с новыми именами:
случай 1: сохранить оригинальные столбцы
В отличие от опций a.1, a.2 и a.3, dplyr сохранит существующие столбцы без изменений и создаст новые столбцы в этом подходе. Имена новых столбцов равны именам именованного вектора, который вы создали заранее (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
случай 2: удалить оригинальные столбцы
Как видите, этот подход сохраняет существующие столбцы без изменений и добавляет новые столбцы с указанными именами. Если вы не хотите сохранять исходные столбцы, а только недавно созданные столбцы (и другие столбцы), вы можете просто добавить select
заявление потом:
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
б) более 1 функции применяется в mutate_each
/ summarise_each
б.1 Позвольте dplyr выяснить новые имена
Если вы применили более 1 функции, вы можете позволить dplyr самостоятельно определять имена (и он сохранит существующие столбцы):
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
б.2 Вручную указать новые имена столбцов
Другой вариант, если используется более 1 функции, это указать расширение имени столбца самостоятельно:
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
Как я могу выбрать определенные столбцы, которые я хочу изменить, как я сделал с select в первом случае?
Вы можете сделать это, ссылаясь на столбцы, которые должны быть видоизменены (или опущены), указав их имена как здесь (mutate Sepal.Length, но не Species):
iris %>% mutate_each(funs(sum), Sepal.Length, -Species) %>% head()
Кроме того, вы можете использовать специальные функции для выбора столбцов, которые должны быть изменены, все столбцы, которые начинаются с определенного слова или содержат его и т. Д., Используя, например:
iris %>% mutate_each(funs(sum), contains("Sepal"), -Species) %>% head()
Для получения дополнительной информации об этих функциях см. ?mutate_each
а также ?select
,
Изменить 1 после комментария:
Если вы хотите использовать стандартную оценку, dplyr предоставляет SE-версии большинства функций, заканчивающиеся дополнительным "_". Так что в этом случае вы бы использовали:
x <- c("Sepal.Width", "Sepal.Length") # vector of column names
iris %>% mutate_each_(funs(sum), x) %>% head()
Обратите внимание на mutate_each_
Я использовал здесь.
Редактировать 2: обновлено с опцией а.4
mutate_each
будет устаревшим, рассмотрите возможность использования mutate_at
, От dplyr_0.5.0
документация:
В будущем mutate_each () и summarise_each () будут устаревшими в пользу более интересного семейства функций: mutate_all (), mutate_at (), mutate_if (), summarise_all (), summarise_at () и summarise_if ().
Применить функцию ко всем переменным, кроме Species
:
Предупреждение: параметр.cols устарел, см. Примечание внизу!
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
Применить функцию к подмножеству переменных
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
Обновить! для версии dplyr 0.7.1 (2017-08-08)
Если вы видите сообщение:
.cols
был переименован и устарел, пожалуйста, используйте.vars
затем изменить .cols
от .vars
,
iris %>% mutate_at(.vars=vars(-Species), .funs=funs(mysum = sum(.))) %>% head()
Другой пример:
iris %>% mutate_at(.vars=vars(Sepal.Width), .funs=funs(mysum = sum(.))) %>% head()
Эквивалентно:
iris %>% mutate_at(.vars=vars("Sepal.Width"), .funs=funs(mysum = sum(.))) %>% head()
Кроме того, в этой версии mutate_each
устарела:
mutate_each()
устарела. использованиеmutate_all()
,mutate_at()
или жеmutate_if()
вместо. На картуfuns
по выбору переменных, используйтеmutate_at()