现在我有两个数据帧。一个包含超过1,100万行的开始日期,结束日期和其他变量。第二个数据框包含加热度日的每日值(基本上是温度测量值)。
set.seed(1)
library(lubridate)
date.range <- ymd(paste(2008,3,1:31,sep="-"))
daily <- data.frame(date=date.range,value=runif(31,min=0,max=45))
intervals <- data.frame(start=daily$date[1:5],end=daily$date[c(6,9,15,24,31)])
实际上,我的每日数据帧每天都有9年,而我的间隔数据帧的条目跨越这段时间内的任意日期。我想要做的是在名为intervals
的{{1}}数据框中添加一个列,该列对每天对应于该时间间隔的值进行求和(结束独占)。
例如,在这种情况下,此新列的第一个条目将是
nhdd
,第二个是
sum(daily$value[1:5])
我尝试使用以下代码
sum(daily$value[2:8]) and so on.
这不起作用,我认为它可能与没有正确引用列有关,但我不知道该去哪里。
我真的想使用intervals <- mutate(intervals,nhdd=sum(filter(daily,date>=start&date<end)$value))
来解决这个问题,而不是循环,因为使用dplyr需要1100万行才能解决这个问题。我尝试使用更多dplyr
,但dplyr似乎不支持Period类。
修改:我实际上现在使用的是lubridate
而不是as.Date
的日期,但是如何从lubridate
中引用不同的数据框的基本问题仍然存在
答案 0 :(得分:4)
eps <- .Machine$double.eps
library(dplyr)
intervals %>%
rowwise() %>%
mutate(nhdd = sum(daily$value[between(daily$date, start, end - eps )]))
# start end nhdd
#1 2008-03-01 2008-03-06 144.8444
#2 2008-03-02 2008-03-09 233.4530
#3 2008-03-03 2008-03-15 319.5452
#4 2008-03-04 2008-03-24 531.7620
#5 2008-03-05 2008-03-31 614.2481
如果您发现dplyr
解决方案位有点慢(主要是由于rowwise
),您可能希望将data.table
用于纯粹的速度
library(data.table)
setkey(setDT(intervals), start, end)
setDT(daily)[, date1 := date]
foverlaps(daily, by.x = c("date", "date1"), intervals)[, sum(value), by=c("start", "end")]
# start end V1
#1: 2008-03-01 2008-03-06 144.8444
#2: 2008-03-02 2008-03-09 233.4530
#3: 2008-03-03 2008-03-15 319.5452
#4: 2008-03-04 2008-03-24 531.7620
#5: 2008-03-05 2008-03-31 614.2481