dplyr中的mutate_each / summarise_each:如何选择某些列并为变异列赋予新名称?

时间:2014-11-19 21:29:49

标签: r dataframe dplyr

我对dplyr动词mutate_each.

感到有点困惑

使用基本的mutate将一列数据转换为z-scores,并在data.frame中创建一个新列(此处的名称为{{},这非常简单明了。 1}}):

z_score_data

但是,由于我有很多数据列,我想转换,看来我应该使用newDF <- DF %>% select(one_column) %>% mutate(z_score_data = one_column - (mean(one_column) / sd(one_column)) 动词。

mutate_each

到目前为止一切顺利。但到目前为止,我还没能弄明白:

  1. 如何在newDF <- DF %>% mutate_each(funs(scale))
  2. 中为这些新列提供适当的名称
  3. 如何选择我想改变的某些列,就像我在第一种情况下使用mutate一样?
  4. 感谢您的帮助。

2 个答案:

答案 0 :(得分:103)

dplyr的更新&gt; = 0.4.3.9000

在dplyr开发版本0.4.3.9000(撰写本文时),mutate_eachsummarise_each内的命名已经简化,如News中所述:

  

summarise_each()mutate_each()的命名行为   调整,以便你可以强制包含功能和   变量名称:summarise_each(mtcars, funs(mean = mean), everything())

如果您只想在mutate_each / summarise_each中应用1个函数并且想要为这些列添加新名称,这一点非常重要。

为了显示差异,这里是使用新命名功能的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

如果您不提供新名称而且只提供1个功能,则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

我认为这个新功能将在下一个版本0.4.4中通过CRAN提供。


dplyr verions&lt; = 0.4.3:

  

如何为这些新列提供适当的名称,就像我可以使用的那样   突变

a)在mutate_each / summarise_each

中应用了1个函数

如果您只在mutate_eachsummarise_each中应用1个函数,则现有列将被转换,名称将保持原样,除非您提供命名向量到mutate_each_ / summarise_each_(参见选项a.4)

以下是一些例子:

a.1仅1个功能 - &gt;将保留现有名称

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如果您指定新的列名称扩展名:

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每列手动指定一个新名称(但仅适用于少数列):

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使用命名向量创建具有新名称的其他列:

案例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

b)在mutate_each / summarise_each

中应用了多个功能

b.1让dplyr找出新名称

如果你应用了多个函数,你可以让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

b.2手动指定新列名

使用多个函数时,另一个选项是自己指定列名扩展名:

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
  

如何选择我希望变异的某些列,就像我一样   在第一种情况下选择?

你可以通过在这里给出他们的名字来引用要变异(或遗漏)的列来做到这一点(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:使用选项a.4更新

答案 1 :(得分:13)

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以外的所有变量:

警告:&#39; .cols&#39;不推荐使用param,请参阅底部的注释!

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()