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

到现在为止还挺好。 但是至今我还没有弄明白:

  1. 我怎么能给这些新的列适当的名字,就像我可以在mutate
  2. 我怎样才能select我想变异的某些列,就像我在第一种情况下select的一样?

谢谢你的帮助。

更新dplyr> = 0.4.3.9000

在dplyr开发版本0.4.3.9000(撰写本文时), mutate_eachmutate_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_eachmutate_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()`