代码之家  ›  专栏  ›  技术社区  ›  plausibly_exogenous

根据以前的值更新列值(一旦处理,则始终处理)

  •  0
  • plausibly_exogenous  · 技术社区  · 4 年前

    我想知道是否有一种更快的方法,使用data.table/dplir按组替换基于先前值的值。

    假设我的原始数据表如下:

    DT_orig <- data.table(name = c("A", "A", "A", "B", "B", "B"), 
                          year = c("2001", "2002", "2003", "2001", "2002", "2003"),
                          treat = c(1,0,0, 0,0,1))
    

    这看起来如下:

     name year treat
    1:    A 2001     1
    2:    A 2002     0
    3:    A 2003     0
    4:    B 2001     0
    5:    B 2002     0
    6:    B 2003     1
    

    在这里,对于每个人(姓名)和时间段(年份),都有一个列(治疗),表明他们是否被分配了治疗。

    我正在考虑一种替代治疗方法,一旦一个人接受治疗,他就会继续接受治疗。因此,修改后的数据表应该如下:

       name year treat
    1:    A 2001     1
    2:    A 2002     1
    3:    A 2003     1
    4:    B 2001     0
    5:    B 2002     0
    6:    B 2003     1
    

    请注意,对于A来说,在2001年接受治疗意味着他们在接下来的几年也会受到“治疗”。

    因为我有一个非常大的数据表,我想知道是否有一种非常快速的修改方法来实现这一点。

    1 回复  |  直到 4 年前
        1
  •  4
  •   akrun    4 年前

    也许我们可以用 cummax (从 base R )

    DT_orig[, treat := cummax(treat), name]
    DT_orig
    #   name year treat
    #1:    A 2001     1
    #2:    A 2002     1
    #3:    A 2003     1
    #4:    B 2001     0
    #5:    B 2002     0
    #6:    B 2003     1
    

    或者也可以这样做 dplyr

    library(dplyr)
    DT_orig %>%
        group_by(name) %>%
        mutate(treat = cummax(treat))
    

    或使用 基数R

    DT_orig$treat <- with(DT_orig, ave(treat, name, FUN = cummax))
    
        2
  •  0
  •   s_baldur    4 年前

    我会用 cummax() 但这里有一个替代说明 data.table 的联接语法:

    DT_orig[, year := as.integer(year)]
    DT_orig[DT_orig[treat == 1], on = .(year >= year, name), treat := 1L]
    
       name year treat
    1:    A 2001     1
    2:    A 2002     1
    3:    A 2003     1
    4:    B 2001     0
    5:    B 2002     0
    6:    B 2003     1