基于R中的事件随时间变化

时间:2017-08-28 00:52:58

标签: r

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

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 UNTIL它们再次出现在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。但是,当我需要来回改变时,我不会认为我所做的事情(使用融化和重塑数据)会起作用。任何帮助都会很棒。感谢。

1 个答案:

答案 0 :(得分: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()的结果。 <{1}}的结果在此处不需要,因为lapply()已就地更新。

先决条件

代码适用于给定的示例。它依赖于假设每个DTID_xEvent1中交替显示,否则可能会失败。

编辑:检查先决条件

下面的版本包括一个检查,如果违反了上述先决条件,则暂停执行(但不是最好的自解释错误消息):

Event2

数据

由OP提供加上四行。

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[]