【问题标题】:Sum a group of columns by row count按行数对一组列求和
【发布时间】:2019-02-17 15:05:50
【问题描述】:

我正在尝试从现有数据集创建一个新数据集。新数据集应该结合原始数据集中的 60 行,以便将每秒发生的事件总和转换为每分钟的事件总数。列数一般不会提前知道。

例如,对于这个数据集,如果我们将其分成 3 行一组:

d1
  a b c d
1 1 1 0 1
2 0 1 0 1
3 0 1 0 0
4 0 0 1 0
5 0 0 1 0
6 1 0 0 0

我们会得到这个data.frame。第 1 行包含 d1 的第 1-3 行的列总和,第 2 行包含 d1 的第 4-6 行的列总和:

d2
  a b c d
1 1 3 0 2
2 1 0 2 0

我已经尝试过d2<-colSums(d1[seq(1,NROW(d1),3),]),这与我所能得到的差不多。

我还考虑了来自 How to sum rows based on multiple conditions - R?How to select every xth row from tableRemove last N rows in data frame with the arbitrary number of rowssum two columns in RMerging multiple rows into single row 的建议。我完全没主意了。任何帮助将不胜感激。

【问题讨论】:

    标签: r


    【解决方案1】:

    创建一个分组变量,group_by那个变量,然后summarise_all

    # your data
    d <- data.frame(a = c(1,0,0,0,0,1),
                    b = c(1,1,1,0,0,0),
                    c = c(0,0,0,1,1,1),
                    d = c(1,1,0,0,0,0))
    
    # create the grouping variable 
    d$group <- rep(c("A","B"), each = 3)
    
    # apply the mean to all columns
    library(dplyr)
    d %>% 
      group_by(group) %>% 
      summarise_all(funs(sum))
    

    返回:

    # A tibble: 2 x 5
      group     a     b     c     d
      <chr> <dbl> <dbl> <dbl> <dbl>
    1 A         1     3     0     2
    2 B         1     0     3     0
    

    【讨论】:

    • 感谢您的回复,Rich。感谢您抽出宝贵时间。
    【解决方案2】:

    概述

    阅读Split up a dataframe by number of rows 后,我意识到您唯一需要知道的就是您希望如何split() d1

    在这种情况下,您希望根据每 3 行将 d1 拆分为多个数据框。在这种情况下,您使用 rep() 指定您希望序列中的每个元素 - 1:2 - 重复三次(行数除以序列的长度)。

    之后,逻辑涉及使用map()d1 %&gt;% split() 之后创建的每个数据框的每一列求和。在这里,summarize_all() 很有帮助,因为您不需要提前知道列名。

    计算完成后,您可以使用bind_rows() 将所有观察结果堆叠回一个数据框。

    # load necessary package ----
    library(tidyverse)
    
    # load necessary data ----
    df1 <-
      read.table(text = "a b c d
    1 1 0 1
    0 1 0 1
    0 1 0 0
    0 0 1 0
    0 0 1 0
    1 0 0 0", header = TRUE)
    
    # perform operations --------
    df2 <-
      df1 %>%
      # split df1 into two data frames
      # based on three consecutive rows
      split(f = rep(1:2, each = nrow(.) / length(1:2))) %>%
      # for each data frame, apply the sum() function to all the columns
      map(.f = ~ .x %>% summarize_all(.funs = funs(sum))) %>%
      # collapse data frames together
      bind_rows()
    
    # view results -----
    df2
    #   a b c d
    # 1 1 3 0 2
    # 2 1 0 2 0
    
    # end of script #
    

    【讨论】:

    • 感谢您的回复,克里斯蒂安。我最初应该提到的一个问题是数据没有输出成整齐的倍数。继续上面的示例,我们可以说输入数据集 d1 可能是 8 行,但需要除以 3。最后几行可以丢弃,但鉴于您和 @RichPauloo 的答案都假定我们知道计数提前。我希望我能够强迫它适应,但似乎并非如此。感谢您提供任何进一步的意见,并为一开始没有更清楚而道歉。
    • 请忽略。我能够通过提前获取数据的子集(等于 3 的倍数)来解决此问题,并使用它创建一个可用于 rep()length() 的变量,使用 n&lt;-trunc((as.numeric(NROW(d1)))/3)
    • 很高兴至少为您指明了正确的方向!很高兴您能够解决。
    猜你喜欢
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 2020-08-21
    • 1970-01-01
    • 2020-11-26
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多