在两个数据帧之间使用dplyr :: mutate根据日期范围创建列

时间:2015-03-31 16:02:17

标签: r dplyr

现在我有两个数据帧。一个包含超过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中引用不同的数据框的基本问题仍然存在

1 个答案:

答案 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
相关问题