我的问题涉及到在整个数据帧的多个列的求和值和创建对应于使用dplyr
这个总和的新列。在列中的数据项是二进制(0,1)。我想到的是summarise_each
的逐行模拟或mutate_each
的dplyr
功能。下面是数据帧的最小例如:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
> df
x1 x2 x3 x4 x5
1 1 1 0 1 1
2 0 1 1 0 1
3 0 NA 0 NA NA
4 NA 1 1 1 1
5 0 1 1 0 1
6 1 0 0 0 1
7 1 NA NA NA NA
8 NA NA NA 0 1
9 0 0 0 0 0
10 1 1 1 1 1
我可以使用类似:
df <- df %>% mutate(sumrow= x1 + x2 + x3 + x4 + x5)
但这涉及编写出每一列的名称。我有一个50列。此外,列名在这我要实现这个操作循环的不同迭代改变,所以我想尝试避免给任何列名。
我该怎么做最有效?任何援助将不胜感激。
怎么样
总结下来每列
df %>%
replace(is.na(.), 0) %>%
summarise_all(funs(sum))
总结每一行
df %>%
replace(is.na(.), 0) %>%
mutate(sum = rowSums(.[1:5]))
我会用正则表达式匹配,总结了一定的模式名称的变量。例如:
df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))
这样,你可以创建多个变量某组数据帧的变量的总和。
如果你只想总结某些列,我会使用这样的:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>% select(x3:x5) %>% rowSums(na.rm=TRUE) -> df$x3x5.total
head(df)
这样,您就可以使用dplyr::select
的语法。
我经常遇到这样的问题,而要做到这一点最简单的方法是使用apply()
命令中mutate
功能。
library(tidyverse)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>%
mutate(sum = select(., x1:x5) %>% apply(1, sum, na.rm=TRUE))
在这里,你可以使用任何你想使用标准dplyr
技巧(例如starts_with()
或contains()
)来选择列。通过这样做单一mutate
命令中所有的工作,可以在处理步骤的dplyr
流中的任何地方发生这种行为。最后,通过使用apply()
功能,你必须使用任何你需要的摘要,包括你自己的目的建造的聚合功能的灵活性。
或者,如果使用非tidyverse功能的想法是不吸引人的,那么你可以收集起来的列,总结并将最后加入结果返回到原始数据帧。
df <- df %>% mutate( id = 1:n() ) # Need some ID column for this to work
df <- df %>%
group_by(id) %>%
gather('Key', 'value', starts_with('x')) %>%
summarise( Key.Sum = sum(value) ) %>%
left_join( df, . )
这里我用了starts_with()
功能选择列和计算的总和,你可以做你想要NA
值什么的。这样做的缺点的方法是,虽然它是非常灵活的,它并没有真正适合的数据清洗步骤dplyr
流。
从reduce()
使用purrr
比rowSums
稍快和肯定比apply
更快,因为你避免遍历所有的行,只是采取量化操作的优势:
library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), `+`))
见this用于计时