从数据框中提取事件行

Extracting event rows from a data frame

我有这个数据框:

df <-
ID  var TIME  value  method
 1   3   0     2      1
 1   3   2     2      1
 1   3   3     0      1
 1   4   0     10     1
 1   4   2     10     1
 1   4   4     5      1 
 1   4   6     5      1        
 2   3   0     2      1
 2   3   2     2      1
 2   3   3     0      1
 2   4   0     10     1
 2   4   2     10     1
 2   4   4     5      1 
 2   4   6     5      1   

我想提取具有新事件输入 value 列的行。例如,对于 ID=1var=3TIME=0 处有 2value。该值在 TIME=1 处保持不变,因此我将仅在 TIME=0 处获取第一行并丢弃第二行。然而,第三行,var=3的值变成了zero,所以我也必须提取这一行。其余变量依此类推。这必须应用于每个主题 ID。对于上面的df,结果应该是这样的:

dfevent <-  
ID  var TIME  value  method
 1   3   0     2      1
 1   3   3     0      1
 1   4   0     10     1
 1   4   4     5      1 
 2   3   0     2      1
 2   3   3     0      1
 2   4   0     10     1
 2   4   4     5      1 

谁能帮我用 R 做这个?我有一个庞大的数据集,我想为每个 var 的值提取新事件发生时的信息。我在编号为(3、4、5、6 和 7)的数据框中有 4 个变量。以上是2个变量的例子(变量号:3和4)

这是使用 dplyr

实现的
 library(dplyr)

 df %>% 
  group_by(ID, var) %>%
  mutate(tf = ifelse(value==lag(value), 1, 0))  %>%
  filter(is.na(tf) | tf==0) %>%
  select(-tf)


#  ID var TIME value method
#1  1   3    0     2      1
#2  1   3    3     0      1
#3  1   4    0    10      1
#4  1   4    4     5      1
#5  2   3    0     2      1
#6  2   3    3     0      1
#7  2   4    0    10      1
#8  2   4    4     5      1

基本上,我创建了一个额外的变量,当值与唯一 ID/var 组合组中的前一行相同时,该变量 returns 为“1”。然后我们在返回输出之前去掉这个变量。

基本解决方案:

df[with(df, abs(ave(value,ID,FUN=function(x) c(1,diff(x)) ))) > 0,]

#   ID var TIME value method
#1   1   3    0     2      1
#3   1   3    3     0      1
#4   1   4    0    10      1
#6   1   4    4     5      1
#8   2   3    0     2      1
#10  2   3    3     0      1
#11  2   4    0    10      1
#13  2   4    4     5      1

从预期的结果来看,您也可以尝试 rleid from data.table

library(data.table)#data.table_1.9.5
 setDT(df)[df[, .I[1L] , list(ID, var, rleid(value))]$V1]
#    ID var TIME value method
#1:  1   3    0     2      1
#2:  1   3    3     0      1
#3:  1   4    0    10      1
#4:  1   4    4     5      1
#5:  2   3    0     2      1
#6:  2   3    3     0      1
#7:  2   4    0    10      1
#8:  2   4    4     5      1

或与@thelatemail

类似的方法
setDT(df)[df[, .I[abs(c(1,diff(value)))>0] , ID]$V1]

unique(setDT(df)[, id:=rleid(value)], by=c('ID', 'var', 'id'))