根据其他列中的条件标记列中值的连续出现

时间:2019-11-19 17:55:01

标签: r

问题的详细信息:我创建了一个玩具示例。每个人都有一个时间序列响应向量,该向量指示对象在整个时间序列中是在睡觉,进食还是步行。出于该示例的目的,紧接在“睡眠”之后发生的所有“进食”连续出现都是很重要的。我有一种情况,我创建了一个计数器变量,该变量计算向量中相同响应的连续出现。但是,我只希望保留或标记在睡眠后发生的“吃”的连续计数。

在下面的代码中:我创建了一个lag-1变量,然后为睡眠后的每个“ eat”实例创建一个标志。但是,这仅标记“ eat”的每个实例的开始,并且我希望标记“ sleep”之后出现的“ eat”的所有出现,以便我可以基于下面的代码中的counter变量创建摘要统计信息。

我坚持如何解决这个问题。

代码如下:

# load libraries
packs <- c('data.table', 'dplyr')
lapply(packs, require, character.only = TRUE)

# 1. initiate data
df <- data.frame(
    id = c(rep(101, 6), rep(102, 8)),
    response = c('sleep', 'sleep', 'sleep', 'eat', 'eat', 'walk', 'walk', 'sleep', 'sleep', 'eat', 'eat', 'walk', 'eat', 'walk'))

# 2. create the lag-1 variable and flag for that start of all occurrences of 
df <- df %>%
    mutate(lag_response = lag(response, 1),
    flag = case_when(lag_response == 'sleep' & response == "eat" ~ 1)) %>%
    select(id, lag_response, response, flag)

# 3. create consecutive counter for responses 
df <- transform(df, counter = ave(c(response), rleid(id, c(response)), FUN = seq_along))

# 4. example of desired column 
df <- df %>%
    mutate(
    desired_col = c(0,0,0,1,1,0,0,0,0,1,1,0,0,0))

2 个答案:

答案 0 :(得分:3)

我们可以通过使用lead(由“ response”的rleid分组的mutate)比较“ sleep”的“ response”值和下一个值为“ eat”的值来创建“ flag” {1}}'flag'通过更改为any为真

library(dplyr)
library(data.table)
df %>% 
   mutate(flag = lag(response == 'sleep' & lead(response) == 'eat', 
                     default = FALSE))  %>% 
   group_by(grp = rleid(response)) %>% 
   mutate(flag = +any(flag)) %>% 
   ungroup %>%
   select(-grp)

答案 1 :(得分:3)

base 中,您可以使用ave。要获得从sleepeat的翻转,您可以简单地与移位索引进行比较。要将匹配内容传播到随后的所有eats,请使用diffcumsum定义组。

df$f <- ave(c(FALSE, df$response[-nrow(df)] == "sleep" & df$response[-1] == "eat")
  , cumsum(c(FALSE, diff(unclass(df$response)) != 0))
  , FUN=function(x) x[1])
df
#    id response     f
#1  101    sleep FALSE
#2  101    sleep FALSE
#3  101    sleep FALSE
#4  101      eat  TRUE
#5  101      eat  TRUE
#6  101     walk FALSE
#7  102     walk FALSE
#8  102    sleep FALSE
#9  102    sleep FALSE
#10 102      eat  TRUE
#11 102      eat  TRUE
#12 102     walk FALSE
#13 102      eat FALSE
#14 102     walk FALSE