跨越与dplyr多列求和

问题描述 投票:63回答:5

我的问题涉及到在整个数据帧的多个列的求和值和创建对应于使用dplyr这个总和的新列。在列中的数据项是二进制(0,1)。我想到的是summarise_each的逐行模拟或mutate_eachdplyr功能。下面是数据帧的最小例如:

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列。此外,列名在这我要实现这个操作循环的不同迭代改变,所以我想尝试避免给任何列名。

我该怎么做最有效?任何援助将不胜感激。

r dplyr
5个回答
73
投票

怎么样

总结下来每列

df %>%
   replace(is.na(.), 0) %>%
   summarise_all(funs(sum))

总结每一行

df %>%
   replace(is.na(.), 0) %>%
   mutate(sum = rowSums(.[1:5]))

26
投票

我会用正则表达式匹配,总结了一定的模式名称的变量。例如:

df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
                    sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))

这样,你可以创建多个变量某组数据帧的变量的总和。


22
投票

如果你只想总结某些列,我会使用这样的:

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的语法。


12
投票

我经常遇到这样的问题,而要做到这一点最简单的方法是使用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流。


7
投票

reduce()使用purrrrowSums稍快和肯定比apply更快,因为你避免遍历所有的行,只是采取量化操作的优势:

library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), `+`))

this用于计时

© www.soinside.com 2019 - 2024. All rights reserved.