根据以前的值更新列值(一次处理总是处理)

Posted

技术标签:

【中文标题】根据以前的值更新列值(一次处理总是处理)【英文标题】:Updating column values based on previous values (once treated always treated) 【发布时间】:2020-05-05 21:58:35 【问题描述】:

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

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

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】:

也许我们可以使用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))

或使用base R

DT_orig$treat <- with(DT_orig, ave(treat, name, FUN = cummax))

【讨论】:

这正是我想要的,非常简单!谢谢!当我被允许时,我会接受你的回答。 谁在反对该解决方案。我首先带着cummax来到这里 @sindri_baldur 示例显示数据是有序的【参考方案2】:

我会使用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

【讨论】:

以上是关于根据以前的值更新列值(一次处理总是处理)的主要内容,如果未能解决你的问题,请参考以下文章

插入和一段时间后更新列值

在 SQL Server 中存储和处理 128 位值

根据 UITextField 中的值禁用按钮只能工作一次(RxSwift)

识别 pyspark 中第一次出现的列值,然后根据它增加另一列

mysql如何根据一列值更新另一列的值?

根据另一列值更新数据框的列