首页 文章

使用dplyr在多个列之间求和

提问于
浏览
52

我的问题涉及在数据框的多个列中汇总值,并使用 dplyr 创建与此求和相对应的新列 . 列中的数据条目是二进制(0,1) . 我正在考虑 dplyrsummarise_eachmutate_each 函数的行方式模拟 . 以下是数据框的最小示例:

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个专栏 . 此外,列名称在我想要实现此操作的循环的不同迭代中发生更改,因此我想尝试避免必须提供任何列名 .

我怎样才能最有效地做到这一点?任何帮助将不胜感激 .

4 回答

  • 58

    怎么样

    总结每一栏

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

    总结每一行

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

    我会使用正则表达式匹配来对具有某些模式名称的变量求和 . 例如:

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

    这样,您可以创建多个变量作为数据框的某些变量组的总和 .

  • 16

    如果你只想对某些列求和,我会使用这样的东西:

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

  • 22

    我经常遇到这个问题,最简单的方法是在 mutate 命令中使用 apply() 函数 .

    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 值执行任何操作 . 这种方法的缺点是虽然它非常灵活,但它并不真正适合数据清理步骤 .

相关问题