【问题标题】:Defining variable by logical subseting on time interval in data.table通过对 data.table 中的时间间隔进行逻辑子集化来定义变量
【发布时间】:2015-05-22 22:14:46
【问题描述】:

我有一个data.table,看起来像这样:

    id event state      time
 1:  A     0  NULL 0.8998250
 2:  A     1  NULL 1.1459127
 3:  A     0  NULL 1.1879722
 4:  A     2  NULL 1.5158930
 5:  A     0  NULL 2.4703966
 6:  B     0  NULL 0.8895393
 7:  B     1  NULL 1.5823427
 8:  B     2  NULL 2.2228495
 9:  B     0  NULL 3.2171193
10:  B     0  NULL 3.8728251
11:  C     1  NULL 0.7085305
12:  C     0  NULL 1.2525965
13:  C     2  NULL 1.8467385
14:  C     0  NULL 2.1358983
15:  C     0  NULL 2.2830119

我想为事件 1 和事件 2 之间的行赋予变量 state 值 1。对于每个 idevent=1,这两个事件只发生一次,总是在 event=2 之前发生。

以下代码生成上述data.table,

library(data.table)

# Defining variabels and data.table
id <- rep(LETTERS[1:3],each=5)
set.seed(123)
event <- c(sample(c(0,1),2,F),sample(c(0,0,2),3,F),
           sample(c(0,1),2,F),sample(c(0,0,2),3,F),
           sample(c(0,1),2,F),sample(c(0,0,2),3,F))
state <- "NULL"
time <- c(apply(matrix(runif(3*5),5,3),2,cumsum))
DT <- data.table(id,event,state,time) 
DT

我已经尝试使用下面的代码将值 1 分配给 event==1event==2 两个时间点之间的状态变量。

DT[time>=time[event==1] & time<=time[event==2],state:="1",by=id]

但这会产生以下输出:

    id event state      time
 1:  A     0  NULL 0.8998250
 2:  A     1  NULL 1.1459127
 3:  A     0     1 1.1879722
 4:  A     2     1 1.5158930
 5:  A     0  NULL 2.4703966
 6:  B     0     1 0.8895393
 7:  B     1  NULL 1.5823427
 8:  B     2     1 2.2228495
 9:  B     0  NULL 3.2171193
10:  B     0  NULL 3.8728251
11:  C     1  NULL 0.7085305
12:  C     0     1 1.2525965
13:  C     2  NULL 1.8467385
14:  C     0     1 2.1358983
15:  C     0  NULL 2.2830119

state=1 明显放置在 data.table 中的错误位置。我无法弄清楚 data.table 在做什么。你能明白为什么 data.table 会以这种方式运行吗?有没有很好的解决方案来解决我的问题?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    不使用ifelse,我们可以使用.I提取行索引,然后将state的那些行分配给'1'。

    DT[DT[,.I[time>=time[event==1] & time<=time[event==2]], 
                                     by=id]$V1, state:='1'][]
    #    id event state      time
    # 1:  A     0  NULL 0.8998250
    # 2:  A     1     1 1.1459127
    # 3:  A     0     1 1.1879722
    # 4:  A     2     1 1.5158930
    # 5:  A     0  NULL 2.4703966
    # 6:  B     0  NULL 0.8895393
    # 7:  B     1     1 1.5823427
    # 8:  B     2     1 2.2228495
    # 9:  B     0  NULL 3.2171193
    #10:  B     0  NULL 3.8728251
    #11:  C     1     1 0.7085305
    #12:  C     0     1 1.2525965
    #13:  C     2     1 1.8467385
    #14:  C     0  NULL 2.1358983
    #15:  C     0  NULL 2.2830119
    

    【讨论】:

      【解决方案2】:

      你快到了,试试这个:

      DT[,state:= ifelse(time>=time[event==1] & time<=time[event==2],1,state),by=id]
      
      #    id event state      time
      # 1:  A     0  NULL 0.8998250
      # 2:  A     1     1 1.1459127
      # 3:  A     0     1 1.1879722
      # 4:  A     2     1 1.5158930
      # 5:  A     0  NULL 2.4703966
      # 6:  B     0  NULL 0.8895393
      # 7:  B     1     1 1.5823427
      # 8:  B     2     1 2.2228495
      # 9:  B     0  NULL 3.2171193
      #10:  B     0  NULL 3.8728251
      #11:  C     1     1 0.7085305
      #12:  C     0     1 1.2525965
      #13:  C     2     1 1.8467385
      #14:  C     0  NULL 2.1358983
      #15:  C     0  NULL 2.2830119
      

      【讨论】:

      • 谢谢!效果很好!
      • 您过滤了time[event==1] &amp; time&lt;=time[event==2] 的第一行,然后按id 分组。您可以通过 dt[time&gt;=time[event==1] &amp; time&lt;=time[event==2],] 看到这一点
      猜你喜欢
      • 2015-04-13
      • 2021-06-20
      • 1970-01-01
      • 2021-07-23
      • 2022-01-05
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 2016-12-01
      相关资源
      最近更新 更多