更改所有进一步观察的变量

时间:2017-08-27 22:22:43

标签: r

我正在尝试创建一种"开关"在我的数据中,当特定事件发生时,二进制指示符将从1切换到0以进行所有下一次观察(按时间排序的数据)。以下是我目前的数据样本。

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

然后这就是我想要的:

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

正如您所看到的,当" EVENT"取0以外的值,我希望与EVENT值匹配的变量从1切换到0,并且我希望它保持为0,因为观察继续进行。任何帮助都会很棒。

感谢。

2 个答案:

答案 0 :(得分:4)

我会使用library(data.table)执行此操作,创建事件发生时间的“查找”表,然后使用non-equi联接更新事件后的值

## extract just the rows where the updates occur
eventRows <- df[df$Event != "0", c("Time", "Event")]

library(data.table)

## set as data.tables
setDT(eventRows)
setDT(df)

## melt into long-form
df_melted <- melt(df, id.vars = c("Time", "Event"))

## perform a non-equi join, and update-by-reference the values
## meeting the criteria
df_melted[
  eventRows
  , on = .(variable == Event, Time >= Time)
  , value := 0
]

## put back into wide form
df_res <- dcast(df_melted, formula = Time + Event ~ variable)
df_res
#    Time Event ID_1 ID_2 ID_3 ID_4 ID_5
# 1:    1     0    1    1    1    1    1
# 2:    2     0    1    1    1    1    1
# 3:    3     0    1    1    1    1    1
# 4:    4     0    1    1    1    1    1
# 5:    5  ID_2    1    0    1    1    1
# 6:    6     0    1    0    1    1    1
# 7:    7  ID_3    1    0    0    1    1
# 8:    8     0    1    0    0    1    1

## convert back to a data.frame using
## setDF(df)

数据

df <- read.table(text = "Time Event ID_1 ID_2 ID_3 ID_4 ID_5
1    0     1    1    1    1    1
                 2    0     1    1    1    1    1
                 3    0     1    1    1    1    1
                 4    0     1    1    1    1    1
                 5    ID_2  1    1    1    1    1
                 6    0     1    1    1    1    1
                 7    ID_3  1    1    1    1    1
                 8    0     1    1    1    1    1", header = T)

答案 1 :(得分:3)

运行cumsum计数器以查看检测到每个变量的位置,然后覆盖相应的变量:

dat[3:7] <- lapply(names(dat[3:7]), function(x) 1-cumsum(dat$Event==x) )
dat

#  Time Event ID_1 ID_2 ID_3 ID_4 ID_5
#1    1     0    1    1    1    1    1
#2    2     0    1    1    1    1    1
#3    3     0    1    1    1    1    1
#4    4     0    1    1    1    1    1
#5    5  ID_2    1    0    1    1    1
#6    6     0    1    0    1    1    1
#7    7  ID_3    1    0    0    1    1
#8    8     0    1    0    0    1    1

此方法不依赖于事先存在的列。

vars <- paste("ID",1:5,sep="_")
dat[vars] <- lapply(vars, function(x) 1-cumsum(dat$Event==x) )