根据另一个表中的并发日期范围划分列值?

时间:2019-08-08 21:06:14

标签: r dataframe dplyr

我有一个带有日级记录的数据框(确保行之间的间隔一致),另一个带有事件数据(事件开始和结束时的event_id)。

多个事件可以同时发生,有时-根本没有事件。

如果一个事件正在进行,我想给它分配df$y,如果同时发生多个事件,则将df$y除以正在进行的事件数,然后平均分配。如果某个事件结束或没有发生,我希望它读取为0。

我想将这些划分作为列添加到日级记录数据帧中,并具有与-

对应的列

date, y, event_1, event_2, event_3

#Time series observations
df = data.frame('date' = c(seq(as.Date('2019-01-01'), as.Date('2019-05-01'), 'day')))
df$y = runif(nrow(df))

df

          date          y
1   2019-01-01 0.71633962
2   2019-01-02 0.18424328
3   2019-01-03 0.69779743
...
#Events observations
df_date = data.frame(
  'event_id'= c(1,2,3),
  'start'= c(as.Date('2018-12-04'), as.Date('2019-01-02'), as.Date('2019-04-15')),
  'end'= c(as.Date('2019-03-02'), as.Date('2019-01-20'), as.Date('2019-05-15'))
)

df_date

  event_id      start        end
1        1 2018-12-04 2019-03-02
2        2 2019-01-02 2019-01-20
3        3 2019-04-15 2019-05-15

2 个答案:

答案 0 :(得分:1)

如果我对您的理解正确,应该采取base R的方法,

for(i in 1:nrow(df_date)) {

     df[,i+2]<- ifelse((df_date$start[i]<=df$date &  
     df_date$end[i]>=df$date),df$y,0) 

     colnames(df)[i+2] <- paste0("event_",i)    

}



df[,3:5] <- (df[,3:5]!=0) * ifelse(rowSums(df[,3:5]!=0)==0,0, df$y/rowSums(df[,3:5]!=0))

head(df)

      date         y      event_1  event_2    event_3
 1 2019-01-01 0.2655087 0.2655087 0.0000000       0
 2 2019-01-02 0.3721239 0.1860619 0.1860619       0
 3 2019-01-03 0.5728534 0.2864267 0.2864267       0
 4 2019-01-04 0.9082078 0.4541039 0.4541039       0
 5 2019-01-05 0.2016819 0.1008410 0.1008410       0
 6 2019-01-06 0.8983897 0.4491948 0.4491948       0

答案 1 :(得分:0)

使用data.table的另一个选项:

library(data.table)
setDT(df)
setDT(df_date)

dcast(
    df_date[df, on=.(start<=date, end>=date)][, y := y / .N, start],
    start ~ event_id, , value.var="y", fill=0)

输出:

          start NA   1   2   3
  1: 2019-01-01  0 1.0 0.0   0
  2: 2019-01-02  0 1.0 1.0   0
  3: 2019-01-03  0 1.5 1.5   0
  4: 2019-01-04  0 2.0 2.0   0
  5: 2019-01-05  0 2.5 2.5   0
 ---                          
117: 2019-04-27  0 0.0 0.0 117
118: 2019-04-28  0 0.0 0.0 118
119: 2019-04-29  0 0.0 0.0 119
120: 2019-04-30  0 0.0 0.0 120
121: 2019-05-01  0 0.0 0.0 121

数据:

df = data.frame('date' = c(seq(as.Date('2019-01-01'), as.Date('2019-05-01'), 'day')))
df$y = as.numeric(1:nrow(df))

df_date = data.frame(
    'event_id'= c(1,2,3),
    'start'= c(as.Date('2018-12-04'), as.Date('2019-01-02'), as.Date('2019-04-15')),
    'end'= c(as.Date('2019-03-02'), as.Date('2019-01-20'), as.Date('2019-05-15'))
)