R 根据组中以前的值创建新的计数变量

R 根据组中以前的值创建新的计数变量,r,dplyr,count,conditional-statements,lag,R,Dplyr,Count,Conditional Statements,Lag,我有一个带有group和time-id的数据帧。现在我想创建一个新的计数变量,称为X2,以每个组中先前的X1值为条件 假设我有以下数据帧、变量组、时间、X1,并希望创建X2。X2的值应该是一个计数变量,指示自X1上次在给定组内等于1以来的周期数,即行数。如果X1之前的所有值均为0,则X2应缺失 group time X1 X2 1 1 1 0 NA 2

我有一个带有group和time-id的数据帧。现在我想创建一个新的计数变量,称为X2,以每个组中先前的X1值为条件

假设我有以下数据帧、变量组、时间、X1,并希望创建X2。X2的值应该是一个计数变量,指示自X1上次在给定组内等于1以来的周期数,即行数。如果X1之前的所有值均为0,则X2应缺失

          group     time       X1        X2 
1          1         1         0         NA  
2          1         2         0         NA  
3          1         3         1         NA  
4          1         4         0         0  
5          1         5         1         1
6          2         1         0         NA  
7          2         2         1         NA  
8          2         3         1         0  
9          2         4         1         0  
10         2         5         0         0  
11         3         1         0         NA  
12         3         2         0         NA  
13         3         3         0         NA  
14         3         4         1         NA  
15         3         5         0         0  
16         4         1         1         NA  
17         4         2         0         0  
18         4         3         0         1  
19         4         4         0         2  
20         4         5         1         3    
我可以通过使用带有cumsum==0的if命令轻松创建NAs。但是,我不知道如何处理其他部分,即创建计数

如果可以使用dplyr,任何帮助都将不胜感激

非常感谢。

使用dplyr包中的pipe%>%、mutate、groupby和lag函数

这确实假设时间差始终为1,如示例数据所示。如果数据中的时间不同,X2应反映时间差异:


这不是很优雅,但它包含了我认为提供的规则

将为X1为1的行号添加一列,并使用fill,以便您可以使用该条件下可用的最新行号

要计算X2_new,如果X1为0,则为组内当前行号减去X1为1的最后一行号之间的差值。如果X1为1且不是组中1的第一个X1,则进行类似的计算,但以之前的rn参考为基础

library(tidyverse)

data_test %>%
  group_by(group) %>%
  mutate(rn = ifelse(X1 == 1, row_number(), NA)) %>%
  fill(rn) %>%
  mutate(X2_new = ifelse(X1 == 0 & row_number() > rn, row_number() - rn - 1, NA),
         X2_new = ifelse(X1 == 1 & !is.na(lag(rn)), row_number() - lag(rn) - 1, X2_new)) %>%
  select(-rn)
输出

library(dplyr)
data_test %>%
  group_by(group) %>%
  mutate(X2 = ifelse(lag(X1) == 1, 0, lag(X2) + 1))
data_test %>%
  group_by(group) %>%
  mutate(X2 = ifelse(lag(X1) == 1, 0, lag(X2) + (time - lag(time))))
library(tidyverse)

data_test %>%
  group_by(group) %>%
  mutate(rn = ifelse(X1 == 1, row_number(), NA)) %>%
  fill(rn) %>%
  mutate(X2_new = ifelse(X1 == 0 & row_number() > rn, row_number() - rn - 1, NA),
         X2_new = ifelse(X1 == 1 & !is.na(lag(rn)), row_number() - lag(rn) - 1, X2_new)) %>%
  select(-rn)
# A tibble: 20 x 5
# Groups:   group [4]
   group  time    X1    X2 X2_new
   <int> <int> <dbl> <dbl>  <dbl>
 1     1     1     0    NA     NA
 2     1     2     0    NA     NA
 3     1     3     1    NA     NA
 4     1     4     0     0      0
 5     1     5     1     1      1
 6     2     1     0    NA     NA
 7     2     2     1    NA     NA
 8     2     3     1     0      0
 9     2     4     1     0      0
10     2     5     0     0      0
11     3     1     0    NA     NA
12     3     2     0    NA     NA
13     3     3     0    NA     NA
14     3     4     1    NA     NA
15     3     5     0     0      0
16     4     1     1    NA     NA
17     4     2     0     0      0
18     4     3     0     1      1
19     4     4     0     2      2
20     4     5     1     3      3