首页 > 解决方案 > 使用数据表查找自 R 中发生相反事件以来的观察次数

问题描述

我希望在数据表中创建一个新变量,该变量添加一个列,告诉我自相反(或其他事件发生)以来的天数。

我拥有的数据集如下所示:

  date     event  id obs_since_event_1 obs_since_event_2
2000-07-06     2  1        NA                 NA
2000-07-07     1  1        NA                 1
2000-07-09     0  1        1                  2
2000-07-10     0  1        2                  3
2000-07-15     2  1        3                  4
2000-07-16     1  1        4                  1
2000-07-20     0  1        1                  2
2000-07-21     1  1        2                  3
2000-07-06     1  2        NA                 NA
2000-07-07     2  2        1                  NA
2000-07-15     0  2        2                  1
2000-07-16     0  2        3                  2
2000-07-17     2  2        4                  3
2000-07-18     1  2        5                  1

我希望添加一个名为 days_since_opposite 的列。记录自相反事件发生以来的天数(相反事件为 1 和 2)。我已经知道事件 1 或 2 发生后的天数。现在我需要制定一个适用于数据表的 if 语句,它将在最后一列中为我提供相应的值。

  date     event  id obs_since_event_1 obs_since_event_2 days_since_opposite
2000-07-06     2  1        NA                 NA                  NA
2000-07-07     1  1        NA                 1                   NA
2000-07-09     0  1        1                  2                   NA
2000-07-10     0  1        2                  3                   NA
2000-07-15     2  1        3                  4                   3
2000-07-16     1  1        4                  1                   1
2000-07-20     0  1        1                  2                   NA
2000-07-21     1  1        2                  3                   3

我希望这很清楚。我也有不同的 id 可以考虑,但不确定它是否会影响结果。

我尝试了以下几行但没有奏效:

data[,days_since_opposite:=ifelse(event==1,obs_since_event_2,ifelse(event==2,obs_since_event_1,0)),]

提前致谢

数据

Input = (
  '  date     event  id obs_since_event_1 obs_since_event_2
2000-07-06     2  1        NA                 NA
2000-07-07     1  1        NA                 1
2000-07-09     0  1        1                  2
2000-07-10     0  1        2                  3
2000-07-15     2  1        3                  4
2000-07-16     1  1        4                  1
2000-07-20     0  1        1                  2
2000-07-21     1  1        2                  3
2000-07-06     1  2        NA                 NA
2000-07-07     2  2        1                  NA
2000-07-15     0  2        2                  1
2000-07-16     0  2        3                  2
2000-07-17     2  2        4                  3
2000-07-18     1  2        5                  1')
df = read.table(textConnection(Input), header = T)

标签: rdataframeif-statementdatatables

解决方案


这是一个选项:

#identify the opposite event
DT[, oppev := c(0L, 2L, 1L)[event + 1L]]

#for event 1 and 2, perform non-equi join to find the prev opp event
DT[event %in% c(1L, 2L), days_since_opposite := DT[.SD, 
    on=.(id, event=oppev, date<date), mult="last", as.integer(i.date - x.date)]]

输出:

          date event id oppev days_since_opposite
 1: 2000-07-06     2  1     1                  NA
 2: 2000-07-07     1  1     2                   1
 3: 2000-07-09     0  1     0                  NA
 4: 2000-07-10     0  1     0                  NA
 5: 2000-07-15     2  1     1                   8
 6: 2000-07-16     1  1     2                   1
 7: 2000-07-20     0  1     0                  NA
 8: 2000-07-21     1  1     2                   6
 9: 2000-07-06     1  2     2                  NA
10: 2000-07-07     2  2     1                   1
11: 2000-07-15     0  2     0                  NA
12: 2000-07-16     0  2     0                  NA
13: 2000-07-17     2  2     1                  11
14: 2000-07-18     1  2     2                   1

数据:

library(data.table)
DT <- fread("date     event  id 
2000-07-06     2  1        
2000-07-07     1  1        
2000-07-09     0  1        
2000-07-10     0  1        
2000-07-15     2  1        
2000-07-16     1  1        
2000-07-20     0  1        
2000-07-21     1  1        
2000-07-06     1  2        
2000-07-07     2  2        
2000-07-15     0  2        
2000-07-16     0  2        
2000-07-17     2  2        
2000-07-18     1  2")[, date := as.IDate(date, format="%Y-%m-%d")]

推荐阅读