【问题标题】:Tracking the first incidence of each episode跟踪每集的首次发生率
【发布时间】:2019-12-19 22:05:36
【问题描述】:

我目前正在使用 R 处理如下所示的数据集:

age  ep  
 1    0   
 2    0   
 3    1   
 4    1   
 5    1   
 6    1   
 7    0   
 8    0   
 9    1   
10    1   
11    0   

我想创建一个变量来跟踪每个系列 ep=1 中第一次出现的 ep=1。这些系列在第一个 ep=1 之前有 ep=0,在每个系列的最后一个 ep=1 之后有 ep=0。

我希望数据集在处理后看起来像这样:

 age  ep  first
 1    0   NA
 2    0   NA
 3    1   1
 4    1   NA
 5    1   NA
 6    1   NA
 7    0   NA
 8    0   NA
 9    1   1
10    1   NA
11    0   NA

我在数据表中工作,因为这个数据集相当大,所以我更喜欢使用数据表的代码来处理数据,但是如果这不可能,我可以转换为数据框并使用其他代码.任何帮助将不胜感激。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    一种快速的data.table 方法...

    library(data.table)
    
    dt <- fread("age  ep  
     1    0   
     2    0   
     3    1   
     4    1   
     5    1   
     6    1   
     7    0   
     8    0   
     9    1   
    10    1   
    11    0")
    
    dt[!shift(ep) & ep, first := 1]
    
    # or more explicit:
    dt[shift(ep) != 1 & ep == 1, first := 1]
    
    dt
    #     age ep first
    #  1:   1  0    NA
    #  2:   2  0    NA
    #  3:   3  1     1
    #  4:   4  1    NA
    #  5:   5  1    NA
    #  6:   6  1    NA
    #  7:   7  0    NA
    #  8:   8  0    NA
    #  9:   9  1     1
    # 10:  10  1    NA
    # 11:  11  0    NA
    

    注意:为了清楚起见,如果您的对象还不是data.table。您可以将其强制为data.table

    setDT(dt)
    

    【讨论】:

    • 在这种特殊情况下,您可以将您的 i 打高尔夫球到 !shift(ep) &amp; ep
    【解决方案2】:

    另一个使用update join的选项

    dt[, first := dt[dt[, .I[1], by=rleid(ep)]$V1][ep == 1][dt, on=.(age), ep]]
    dt
    #    age ep first
    # 1:   1  0    NA
    # 2:   2  0    NA
    # 3:   3  1     1
    # 4:   4  1    NA
    # 5:   5  1    NA
    # 6:   6  1    NA
    # 7:   7  0    NA
    # 8:   8  0    NA
    # 9:   9  1     1
    #10:  10  1    NA
    #11:  11  0    NA
    

    使用@Khaynes 提供的数据

    【讨论】:

      【解决方案3】:

      一种使用fifelse的方法

      dt[, first := fifelse( ep == 1 & shift( ep , type = "lag" ) == 0L, 1L, NA_integer_) ]
      dt
      #    age ep first
      # 1:   1  0    NA
      # 2:   2  0    NA
      # 3:   3  1     1
      # 4:   4  1    NA
      # 5:   5  1    NA
      # 6:   6  1    NA
      # 7:   7  0    NA
      # 8:   8  0    NA
      # 9:   9  1     1
      # 10:  10  1    NA
      # 11:  11  0    NA
      

      【讨论】:

        【解决方案4】:

        另一个更新加入版本,使用mult="first" 只覆盖组中的第一个匹配行:

        dt[, rid := rleid(ep)][dt[ep==1], on=.(rid), mult="first", first := 1]
        dt
        #    age ep rid first
        # 1:   1  0   1    NA
        # 2:   2  0   1    NA
        # 3:   3  1   2     1
        # 4:   4  1   2    NA
        # 5:   5  1   2    NA
        # 6:   6  1   2    NA
        # 7:   7  0   3    NA
        # 8:   8  0   3    NA
        # 9:   9  1   4     1
        #10:  10  1   4    NA
        #11:  11  0   5    NA
        

        【讨论】:

          猜你喜欢
          • 2013-12-03
          • 1970-01-01
          • 1970-01-01
          • 2012-03-07
          • 1970-01-01
          • 2023-02-07
          • 2013-09-20
          • 2020-11-10
          相关资源
          最近更新 更多