我需要对与某个日期范围相对应的值求和,并且需要对许多主题进行此操作。
在下一个示例中,df1包含三个主题的开始和结束日期,df2包含日期及其对应的值:
df1<-data.frame(sub=c("a","b","c"),
start=as.Date(c("2015/10/13","2015/10/13","2015/10/11")),
end=as.Date(c("2015/10/16","2015/10/18","2015/10/15")))
df2<-data.frame(date=seq(as.Date("2015/10/11"), as.Date("2015/10/18"), "days"),
value=c(32,30,28,15,19,23,35,18))
> df1
sub start end
1 a 2015-10-13 2015-10-16
2 b 2015-10-13 2015-10-18
3 c 2015-10-11 2015-10-15
> df2
date value
1 2015-10-11 32
2 2015-10-12 30
3 2015-10-13 28
4 2015-10-14 15
5 2015-10-15 19
6 2015-10-16 23
7 2015-10-17 35
8 2015-10-18 18
我想对df2中的value
从start
日期开始到df1中的end
日期进行求和,我想对每个sub
进行求和(实际上是有很多主题(例如,成对的开始日期和结束日期),所以我认为也许应该使用for
循环)。
我希望这样:
sub sum
a 85
b 138
c 124
其中a = 28 + 15 + 19 + 23,b = 28 + 15 + 19 + 23 + 35 + 18,c = 32 + 30 + 28 + 15 + 19
感谢您的帮助
答案 0 :(得分:1)
一个选项是non-equi
联接而无需使用任何循环
library(data.table)
setDT(df2)[df1, .(sub = sub, sum = sum(value)),
on = .(date >= start, date <= end), by = .EACHI][, .(sub, sum)]
# sub sum
#1: a 85
#2: b 138
#3: c 124
或者以fuzzyjoin
的方式使用tidy
library(fuzzyjoin)
library(dplyr)
fuzzy_left_join(df2, df1, by = c(date = 'start', date = 'end'),
match_fun = list(`>=`, `<=`)) %>%
group_by(sub) %>%
summarise(value = sum(value))
# A tibble: 3 x 2
# sub value
# <fct> <dbl>
#1 a 85
#2 b 138
#3 c 124
答案 1 :(得分:1)
使用mapply
的选项是在start
中的end
和df1
日期之间创建一个日期序列,并将df2
和{ {1}} sum
。
value
答案 2 :(得分:0)
这可以在单个SQL语句中完成,例如:
library(sqldf)
sqldf("select a.sub, sum(b.value) as sum
from df1 as a
left join df2 as b on b.date between a.start and a.end
group by a.sub")
给予:
sub sum
1 a 85
2 b 138
3 c 124