簡體   English   中英

從數據框中提取事件行

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

我想提取具有新的eventin value列的行。 例如,對於ID=1var=3TIME=0value 2 這個值在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 /變量組合的組中的前一行相同時,返回“ 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

從預期的結果,你也可以嘗試rleiddata.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'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM