【发布时间】:2019-07-24 01:41:51
【问题描述】:
给定一个包含短间隔的数据集,以及一个表示每个间隔内某物的平均度量的值,我想将这些值平均到日历年,分别为每个人(“id”)。
问题在于这些间隔与日历年不一致,因此需要对这些值进行时间加权,以便从较短的间隔平均值中获得对年度平均值的最佳估计。
请注意,间隔包含开始日期,不包含结束日期。
示例数据
start_date 和 end_date 是在 id 级别内唯一不重叠的区间:
set.seed(30)
library(lubridate)
library(data.table)
x <- CJ(id=1:5, start_date=seq(from=as.Date("2005-01-12"),by=14,length=100))
#add noise so intervals don't all start on 2005-01-12
x[,start_date:=start_date + rbinom(1,size=20,prob=.15)*15L,by=id]
#all intervals are two weeks:
x[,end_date:=start_date+14]
x[,value:=rnorm(nrow(x))]
#for each id, calculate the mean value over each calendar year.
years <- c(year(min(x$start_date)), year(max(x$start_date)))
附加约束:
- 适用于不完全是两周的间隔
- 即使间隔长度不同(只要 它们不重叠)
- 即使最早的 start_date 各不相同也能正常工作 参与者
- 日历年的平均值,没有足够的周期 完成这一年的 id 应该是 NA
对于我的目的来说太慢的潜在解决方案。
complete_date_seq <- seq(as.Date(ymd(paste0(years[1],"-01-01"))), as.Date(ymd(paste0(years[2],"-12-12"))),by=1)
m <- matrix(NA,nrow=length(unique(x$id)),ncol=length(complete_date_seq))
rownames(m) <- unique(x$id)
colnames(m) <- as.character(complete_date_seq)
for(i in 1:nrow(m)){
temp <- x[id==rownames(m)[i]]
for(j in 1:nrow(temp)){
m[i, as.Date(complete_date_seq) %within% temp[j,interval(start_date,end_date-1)]] <- temp[j,value]
}
}
out <- CJ(id=unique(x$id),year=years[1]:years[2])
intervalfromyear <- function(y) interval(as.Date(ymd(paste0(y,"-01-01"))), as.Date(ymd(paste0(y,"-12-31"))))
out[, annual_avg:=mean(m[rownames(m)==.BY$id,complete_date_seq %within% intervalfromyear(.BY$year)]) ,by=c("id","year")]
我猜有一些我不知道的时间加权包。这是真的?理想情况下,有一个快速的本地 data.table 解决方案。
【问题讨论】:
标签: r data.table lubridate