dplyr中的mutate_each / summarise_each:如何select某些列并为突变的列赋予新的名称?
我对dplyr
动词mutate_each.
有点困惑mutate_each.
使用基本的mutate
将一列数据转换成z分数,并在你的data.frame中创build一个新的列(这里的名字是z_score_data
)是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我想变异的某些列,就像我在第一种情况下
select
的一样?
谢谢你的帮助。
更新dplyr> = 0.4.3.9000
在dplyr开发版本0.4.3.9000(撰写本文时), mutate_each
和mutate_each
内的命名已经简化,如新闻中所述:
mutate_each()
summarise_each()
和mutate_each()
的命名行为已被调整,以便强制包含函数和variables名:summarise_each(mtcars, funs(mean = mean), everything())
如果你想在mutate_each
/ mutate_each
只应用一个函数,并且你想给这些列新的名字,这是非常重要的。
为了显示不同之处,下面是使用新命名function的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
我认为这个新function将在下一个版本0.4.4中通过CRAN提供。
dplyr版本<= 0.4.3:
我怎么能给这些新的列适当的名字,就像我可以在mutate?
a)1个函数应用于mutate_each
/ mutate_each
如果在mutate_each
或mutate_each
只应用了一个函数,那么现有的列将被转换,并且名称将保持mutate_each_
, 除非您提供了一个名为vector的mutate_each_
/ mutate_each_
(参见选项a.4)
这里有些例子:
a.1只有1个function – >会保留现有的名字
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手动为每列指定一个新的名称(但只适用于less数列):
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使用一个已命名的向量创build具有新名称的附加列:
案例1:保留原始栏目
与选项a.1,a.2和a.3相比,dplyr将保持现有列不变,并在此方法中创build新列。 新列的名称等于您预先创build的指定向量的名称(在这种情况下为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:删除原始列
正如你所看到的,这种方法保持现有的列不变,并添加具有指定名称的新列。 如果你不想保留原始列,而只是新创build的列(和其他列),你可以添加一个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
/ mutate_each
应用了1个以上的函数
b.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
b.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我想变异的某些列,就像我在第一种情况下select的一样?
你可以通过在这里引用他们的名字(改变Sepal.Length,但不是物种)来引用要被突变(或遗漏)的列来做到这一点:
iris %>% mutate_each(funs(sum), Sepal.Length, -Species) %>% head()
另外,你可以使用特殊的函数来select要变异的列,所有以某个词开头或包含某个词的列,例如:
iris %>% mutate_each(funs(sum), contains("Sepal"), -Species) %>% head()
有关这些函数的更多信息,请参阅?mutate_each
和?select
。
编辑1评论后:
如果你想使用标准的评估,dplyr提供大多数function的SE版本,以附加的“_”结尾。 所以在这种情况下,你会使用:
x <- c("Sepal.Width", "Sepal.Length") # vector of column names iris %>% mutate_each_(funs(sum), x) %>% head()
注意我在这里使用的mutate_each_
。
编辑2:用选项a.4更新
mutate_each
将被弃用,请考虑使用mutate_at
。 来自dplyr_0.5.0
文档:
在将来,mutate_each()和summarise_each()将被弃用,以支持更多function的函数族:mutate_all(),mutate_at(),mutate_if(),summarise_all(),summarise_at()和summarise_if()。
对Species
以外的所有variables应用一个函数:
警告:'.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
将函数应用于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
更新! for dplyr 0.7.1版本(2017-08-08)
如果您看到以下消息: .cols` has been renamed and is deprecated, please use `.vars
,然后通过.vars
更改.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()` is deprecated. Use `mutate_all()`, `mutate_at()` or `mutate_if()` instead. To map `funs` over a selection of variables, use `mutate_at()`