【问题标题】:Excel SUMIFS equivalent in RR中的Excel SUMIFS等价物
【发布时间】:2014-12-30 12:03:03
【问题描述】:

我对 R 非常陌生,我正在寻找重新创建 Excel VBA 宏和 Excel 工作表函数(如 SUMIFS)的方法。如果该行在其其他列上具有匹配多个条件的条目,则 SUMIFS 对列求和。

我有以下数据框,我想计算一个新列。新列是与Start DateEndDate 范围重叠的所有行的Sample 的总和。例如在1 线上,它将是697(第一个3 lines 的总和)。具体求和的标准:include Sample if EndDate >= StartDate[i] & StartDate <=EndDate[i]

 StartDate   EndDate    Sample  *SUMIFS example*
 10/01/14   24/01/14    139         *697*
 12/01/14   26/01/14    136 
 19/01/14   02/02/14    422 
 25/01/14   08/02/14    762 
 29/01/14   12/02/14    899 
 05/02/14   19/02/14    850 
 07/02/14   21/02/14    602 
 09/02/14   23/02/14    180 
 18/02/14   04/03/14    866 

任何 cmets 或指针将不胜感激。

【问题讨论】:

    标签: r sumifs


    【解决方案1】:

    假设你在一个名为df的数据框中有上述数据:

    sum(df$Sample[EndDate >= df$StartDate & StartDate <= df$EndDate])
    

    即:

    • df$Sample[...] 选择Sample 列,条件在[...] 中指定
    • EndDate &gt;= df$StartDateStartDate &lt;= df$EndDate 来自您的示例,转换为 R 条件,&amp; 介于两者之间,要求两个条件同时为真。请注意,表达式中没有 i 索引。这就是它在 R 中的工作方式,为数据框中的每一行计算表达式,df$Sample[...] 的结果是一个值向量,只有 [...] 中的表达式为 true 的值
    • sum 当然是内置函数来计算总和,自然

    【讨论】:

    • 这并没有给出 OP 想要的内容,对于每一行,他想查看所有其他行并总结样本列(如果它符合条件)。
    • 非常感谢,但正如卡梅伦所说,这并不完全符合我的期望(尽管他总结得很完美)。感谢您的帮助。
    • 认为你的意思是sum(df$Sample[df$EndDate &gt;= df$StartDate &amp; df$StartDate &lt;= df$EndDate])
    【解决方案2】:

    您可以使用循环或笛卡尔合并来执行此操作。我不知道有任何内置函数可以做到这一点。

    library(dplyr)
    
    x = structure(list(StartDate = structure(c(1389312000, 1389484800, 
    1390089600, 1390608000, 1390953600, 1391558400, 1391731200, 1391904000, 
    1392681600), tzone = "UTC", class = c("POSIXct", "POSIXt")), 
        EndDate = structure(c(1390521600, 1390694400, 1391299200, 
        1391817600, 1392163200, 1392768000, 1392940800, 1393113600, 
        1393891200), tzone = "UTC", class = c("POSIXct", "POSIXt"
        )), Sample = c(139L, 136L, 422L, 762L, 899L, 850L, 602L, 
        180L, 866L)), .Names = c("StartDate", "EndDate", "Sample"
    ), row.names = c(NA, -9L), class = "data.frame")
    
    x2 = x
    names(x2)=c('StartDate2','EndDate2','Sample2')
    x3 = merge(x,x2,allow.cartesian =T)
    x4 = summarise(group_by(x3,StartDate,EndDate),
        sumifs=sum(Sample2[EndDate2 >= StartDate & StartDate2 <= EndDate]))
    x_sumifs = merge(x,x4,by=c('StartDate','EndDate'))
    

    这是输出的样子。

    > x_sumifs
       StartDate    EndDate Sample sumifs
    1 2014-01-10 2014-01-24    139    697
    2 2014-01-12 2014-01-26    136   1459
    3 2014-01-19 2014-02-02    422   2358
    4 2014-01-25 2014-02-08    762   3671
    5 2014-01-29 2014-02-12    899   3715
    6 2014-02-05 2014-02-19    850   4159
    7 2014-02-07 2014-02-21    602   4159
    8 2014-02-09 2014-02-23    180   3397
    9 2014-02-18 2014-03-04    866   2498
    

    【讨论】:

      【解决方案3】:

      您可以使用base R 中的lapply/sapply 来执行此操作。 x 来自@cameron.bracken 的帖子。

      x$sumifs <- sapply(seq_len(nrow(x)), function(i) with(x, 
                   sum(Sample[EndDate >= StartDate[i] & StartDate <= EndDate[i]])))
      
      x
      #   StartDate    EndDate Sample sumifs
      #1 2014-01-10 2014-01-24    139    697
      #2 2014-01-12 2014-01-26    136   1459
      #3 2014-01-19 2014-02-02    422   2358
      #4 2014-01-25 2014-02-08    762   3671
      #5 2014-01-29 2014-02-12    899   3715
      #6 2014-02-05 2014-02-19    850   4159
      #7 2014-02-07 2014-02-21    602   4159
      #8 2014-02-09 2014-02-23    180   3397
      #9 2014-02-18 2014-03-04    866   2498
      

      【讨论】:

        【解决方案4】:

        您可以使用 'by' 函数来获取值。在 'by' 中,数据帧按行拆分为由一个或多个因子的值子集的数据帧,并依次将函数应用于每个子集。

        x$sumifs <- by(Sample[EndDate >= StartDate[i] & StartDate <= EndDate[i]],sum)
        

        更多功能详情请见here

        【讨论】:

          猜你喜欢
          • 2021-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-14
          • 2016-02-26
          • 2018-07-18
          • 2016-06-14
          • 2016-05-23
          相关资源
          最近更新 更多