R中的Excel SUMIFS等价物

时间:2014-11-03 18:46:02

标签: r sumifs

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

我有以下数据框,我想计算一个新列。对于与SampleStart Date范围重叠的所有行,新列是EndDate的总和。例如,在1行上,它将是697(第一个3 lines的总和)。具体金额的标准:如果Sample

,则包括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 

任何评论或指示都将不胜感激。

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

假设您在名为df的数据框中包含上述数据:

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

那是:

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

答案 3 :(得分:0)

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

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

有关该功能的更多详细信息,请参见here