【问题标题】:Variable change over time based on event in R基于R中的事件随时间变化的变量
【发布时间】:2017-08-29 18:07:46
【问题描述】:

我有一些时间流逝的数据,我想根据事件更改特定变量。在帮助下,我能够弄清楚如何更改一次值,但我希望能够不断更改它。以下是我开始使用的数据。

Time Event1 Event2  ID_1 ID_2 ID_3 ID_4 ID_5
1    0      0       1    1    1    1    0
2    0      0       1    1    1    1    0
3    0      0       1    1    1    1    0
4    0      0       1    1    1    1    0
5    ID_2   ID_5    1    1    1    1    0
6    0      0       1    1    1    1    0
7    ID_5   ID_2    1    1    1    1    0
8    0      0       1    1    1    1    0

我想要发生的是,当 ID_X 出现在 Event1 中时,我想将该变量中的所有未来值更改为 0,直到它们再次出现在 Event2 中,在这种情况下,我想将它们翻转回 1 . 下面是我想要做的。

更新数据表

Time Event1 Event2  ID_1 ID_2 ID_3 ID_4 ID_5
1    0      0       1    1    1    1    0
2    0      0       1    1    1    1    0
3    0      0       1    1    1    1    0
4    0      0       1    1    1    1    0
5    ID_2   ID_5    1    0    1    1    1
6    0      0       1    0    1    1    1
7    ID_5   ID_2    1    1    1    1    0
8    0      0       1    1    1    1    0

如您所见,ID_2 出现在 Event1 中,开始为 0,然后出现在 Event2 中并且应该被翻转回 1。在一些帮助下我唯一能弄清楚的是如何从其余数据为 1/0。但是,当我需要来回更改内容时,我认为我所做的(使用融化和重塑数据)不会起作用。任何帮助都会很棒。谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    这可以使用cumsum() 的组合来解决,以记录"ID_2" 的出现,例如,在Event1Event2,分别和xor() 翻转。

    library(data.table)
    DT[, ID_2 := 0L + xor(cumsum(Event1 == "ID_2") - cumsum(Event2 == "ID_2"), ID_2)][]
    DT[, ID_5 := 0L + xor(cumsum(Event1 == "ID_5") - cumsum(Event2 == "ID_5"), ID_5)][]
    
        Time Event1 Event2 ID_1 ID_2 ID_3 ID_4 ID_5
     1:    1      0      0    1    1    1    1    0
     2:    2      0      0    1    1    1    1    0
     3:    3      0      0    1    1    1    1    0
     4:    4      0      0    1    1    1    1    0
     5:    5   ID_2   ID_5    1    0    1    1    1
     6:    6      0      0    1    0    1    1    1
     7:    7   ID_5   ID_2    1    1    1    1    0
     8:    8      0      0    1    1    1    1    0
     9:    9   ID_2      0    1    0    1    1    0
    10:   10      0      0    1    0    1    1    0
    11:   11      0   ID_2    1    1    1    1    0
    12:   12      0      0    1    1    1    1    0
    

    请注意,为了证明ID_2 第二次翻转,示例数据集中添加了额外的行。

    如果有很多 ID_x 列,可以使用 lapply() 方便地对每一列重复此操作

    id_cols <- stringr::str_subset(names(DT), "^ID")
    invisible(lapply(id_cols, function(col) 
      DT[, (col) := 0L + xor(cumsum(Event1 == col) - cumsum(Event2 == col), get(col))]))
    DT[]
    

    结果同上。

    使用

    data.table 是因为它允许就地更新单个列,即无需复制整个数据集,从而节省内存和时间。 invisible() 阻止打印 lapply() 的结果。这里不需要lapply() 的结果,因为DT 已就地更新。

    先决条件

    代码适用于给定的示例。它依赖于每个ID_x 交替出现在Event1Event2 中的假设,否则很可能会失败。

    编辑:检查先决条件

    下面的版本包括一个检查,如果违反上述先决条件,则停止执行(虽然不是最好的不言自明的错误消息):

    id_cols <- stringr::str_subset(names(DT), "^ID")
    invisible(lapply(id_cols, function(col) 
      DT[, (col) := {
        tmp <- cumsum(Event1 == col) - cumsum(Event2 == col)
        stopifnot(all(tmp %in% -1:1))
        0L + xor(tmp, get(col))
      }]))
    DT[]
    

    数据

    由 OP 提供,加上四行。

    library(data.table)
    DT <- fread(
      "Time Event1 Event2  ID_1 ID_2 ID_3 ID_4 ID_5
      1    0      0       1    1    1    1    0
      2    0      0       1    1    1    1    0
      3    0      0       1    1    1    1    0
      4    0      0       1    1    1    1    0
      5    ID_2   ID_5    1    1    1    1    0
      6    0      0       1    1    1    1    0
      7    ID_5   ID_2    1    1    1    1    0
      8    0      0       1    1    1    1    0
      9    ID_2   0       1    1    1    1    0
     10    0      0       1    1    1    1    0
     11    0      ID_2    1    1    1    1    0
     12    0      0       1    1    1    1    0"
    )
    

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 1970-01-01
      • 2023-03-23
      • 2011-11-26
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      相关资源
      最近更新 更多