根据开始日期和结束日期的数组聚合数据框中的值 - R
Aggregate values in data frame based on an array of start and end dates - R
示例数据:
Date_End <- c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12")
Date_Start <- c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04")
as.Date(Date_Start, "%Y-%m-%d" )
as.Date(Date_End, "%Y-%m-%d" )
df1 <- data.frame(Date_Start,Date_End)
c1 <- data.frame(seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1))
c2 <- sample(100, size = nrow(c1), replace = TRUE)
df2 <- data.frame(c2,c1)
names(df2) <- c("unit","date")
df2 <- zoo(df2)
我在 df1
中有一组开始日期和结束日期,在 df2
中有一个时间序列。我想使用聚合函数(主要是求和),以便在跨越 df1
的每一行的时间段内得到 df2
中的 unit
的总和。例如,产生这样的东西:
Date_Start Date_End sum(unit)
8/24/1999 8/30/1999 282
8/30/1999 9/7/1999 269
9/13/1999 9/20/1999 464
9/20/1999 9/27/1999 308
9/27/1999 10/4/1999 408
10/4/1999 10/12/1999 353
我尝试同时使用 window 函数:
window(df2,start = df1$Date_Start, end = df1$Date_End)
并创建一个序列,然后进行索引:
seq_a <- seq(as.Date(df1$Date_Start), as.Date(df1$Date_End), by = 1)
test <- df2[seq_a]
sum(test)
但是对于seq,你只能有一个开始和结束:
Error in seq.Date(as.Date(df1$Date_Start), as.Date(df1$Date_End), by = 1) :
'from' must be of length 1
感谢帮助!
可能应该使用函数而不是循环,但为了快速而肮脏,您可以这样做:
Date_End <- c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12")
Date_Start <- c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04")
Date_Start <- as.Date(Date_Start, "%Y-%m-%d" )
Date_End <- as.Date(Date_End, "%Y-%m-%d" )
df1 <- data.frame(Date_Start,Date_End)
c1 <- data.frame(seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1))
c2 <- sample(100, size = nrow(c1), replace = TRUE)
df2 <- data.frame(c2,c1)
names(df2) <- c("unit","date")
for (i in 1:nrow(df1)) {
df1$sum[i] <- sum(df2$unit[df2$date > df1$Date_Start[i] & df2$date < df1$Date_End[i]])
}
请注意,我也修改了您代码的第 3 行和第 4 行。
此解决方案不能将 df2
用作 zoo
对象,但它可能对您仍然有用:
Date_End <- as.Date(c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12"))
Date_Start <- as.Date(c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04"))
df1 <- data.frame(Date_Start,Date_End)
c1 <- seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1)
c2 <- sample(100, size = length(c1), replace = TRUE)
df2 <- data.frame(unit = c2, date = c1)
library(sqldf)
> sqldf("select Date_Start, Date_End, sum(unit) as units
from df1,
df2
where df1.Date_Start <= df2.date
and df2.date <= df1.Date_end
group by Date_Start")
Date_Start Date_End units
1 1999-08-24 1999-08-30 258
2 1999-08-30 1999-09-07 493
3 1999-09-13 1999-09-20 423
4 1999-09-20 1999-09-27 432
5 1999-09-27 1999-10-04 433
6 1999-10-04 1999-10-12 584
我编辑了您的一些代码,包括制作 Date_Start
和 Date_End
日期对象以及 c1
向量而不是 data.frame。
P.S。不推荐使用带下划线的大小写,这里是style guide.
示例数据:
Date_End <- c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12")
Date_Start <- c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04")
as.Date(Date_Start, "%Y-%m-%d" )
as.Date(Date_End, "%Y-%m-%d" )
df1 <- data.frame(Date_Start,Date_End)
c1 <- data.frame(seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1))
c2 <- sample(100, size = nrow(c1), replace = TRUE)
df2 <- data.frame(c2,c1)
names(df2) <- c("unit","date")
df2 <- zoo(df2)
我在 df1
中有一组开始日期和结束日期,在 df2
中有一个时间序列。我想使用聚合函数(主要是求和),以便在跨越 df1
的每一行的时间段内得到 df2
中的 unit
的总和。例如,产生这样的东西:
Date_Start Date_End sum(unit)
8/24/1999 8/30/1999 282
8/30/1999 9/7/1999 269
9/13/1999 9/20/1999 464
9/20/1999 9/27/1999 308
9/27/1999 10/4/1999 408
10/4/1999 10/12/1999 353
我尝试同时使用 window 函数:
window(df2,start = df1$Date_Start, end = df1$Date_End)
并创建一个序列,然后进行索引:
seq_a <- seq(as.Date(df1$Date_Start), as.Date(df1$Date_End), by = 1)
test <- df2[seq_a]
sum(test)
但是对于seq,你只能有一个开始和结束:
Error in seq.Date(as.Date(df1$Date_Start), as.Date(df1$Date_End), by = 1) :
'from' must be of length 1
感谢帮助!
可能应该使用函数而不是循环,但为了快速而肮脏,您可以这样做:
Date_End <- c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12")
Date_Start <- c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04")
Date_Start <- as.Date(Date_Start, "%Y-%m-%d" )
Date_End <- as.Date(Date_End, "%Y-%m-%d" )
df1 <- data.frame(Date_Start,Date_End)
c1 <- data.frame(seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1))
c2 <- sample(100, size = nrow(c1), replace = TRUE)
df2 <- data.frame(c2,c1)
names(df2) <- c("unit","date")
for (i in 1:nrow(df1)) {
df1$sum[i] <- sum(df2$unit[df2$date > df1$Date_Start[i] & df2$date < df1$Date_End[i]])
}
请注意,我也修改了您代码的第 3 行和第 4 行。
此解决方案不能将 df2
用作 zoo
对象,但它可能对您仍然有用:
Date_End <- as.Date(c("1999-08-30","1999-09-07","1999-09-20","1999-09-27","1999-10-04","1999-10-12"))
Date_Start <- as.Date(c("1999-08-24" ,"1999-08-30" ,"1999-09-13" ,"1999-09-20" ,"1999-09-27" ,"1999-10-04"))
df1 <- data.frame(Date_Start,Date_End)
c1 <- seq(as.Date('1999-08-24'), as.Date('1999-10-12'), by = 1)
c2 <- sample(100, size = length(c1), replace = TRUE)
df2 <- data.frame(unit = c2, date = c1)
library(sqldf)
> sqldf("select Date_Start, Date_End, sum(unit) as units
from df1,
df2
where df1.Date_Start <= df2.date
and df2.date <= df1.Date_end
group by Date_Start")
Date_Start Date_End units
1 1999-08-24 1999-08-30 258
2 1999-08-30 1999-09-07 493
3 1999-09-13 1999-09-20 423
4 1999-09-20 1999-09-27 432
5 1999-09-27 1999-10-04 433
6 1999-10-04 1999-10-12 584
我编辑了您的一些代码,包括制作 Date_Start
和 Date_End
日期对象以及 c1
向量而不是 data.frame。
P.S。不推荐使用带下划线的大小写,这里是style guide.