0

我试图简单地选择leaded变量的前两个或三个值。

想象一下我的数据看起来像这样

       id variable  leadvar
1       a        0     0
2       a        1     0
3       a        1     0
4       b        0     0
5       b        0     0
6       b        1     0
7       c        0     0
8       c        0     0
9       c        0     0
10      d        1     0
11      d        1     0
12      d        1     0

我想要的是首先lead,variable条件是lead minus 1 = 0(对于每个id)(这意味着1如果 a1前面是,则前导变量应该采用0),例如:

       id variable  leadvar
1       a        0     1
2       a        1     0
3       a        1     0
4       b        0     0
5       b        0     1
6       b        1     0
7       c        0     0
8       c        0     0
9       c        0     0
10      d        1     0
11      d        1     0
12      d        1     0

然后选择前导之后的第一行(以及前导变量本身),如下所示:

       id variable  leadvar
        a        0     1
        a        1     0

        b        0     1
        b        1     0

我在最后一步挣扎。我希望能够自由选择领先后的行数。我怎样才能做到这一点 ?

我的代码是:

为了计算lead

library(dplyr) 

dt = dt %>% group_by(id) %>% mutate(leadvar = ifelse(variable == 0 & lead(variable == 1, default = 0), 1, 0) )

我尝试在引导后选择 2 行,但它不起作用

dt %>% group_by(id) %>% mutate(V4 = variable + leadvar) %>% mutate(m = 1:n()) %>% filter(m < 3)

数据

dt = structure(list(id = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), 
variable = c(0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1), lead = c(1, 
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)), class = "data.frame", .Names = c("id", "variable", "lead"), row.names = c(NA, -12L))
4

1 回答 1

2

使用dplyr有一些解决此问题的方法,第一个涉及创建一个附加变量 ( tailvar ) 以捕获variableleadvar均为 1。由于dplyr不保留行编号,我创建了一个额外的列 ( rowid ) 来演示解决方案选择请求的行。

dt %>% mutate(leadvar = ifelse(variable == 0 & lead(variable) == 1, 1, 0), 
          tailvar = ifelse(lag(leadvar, default = 0) == 1, 1, 0),
          rowid = row_number()) %>% filter(leadvar ==1 | tailvar ==1)

这使:

     id variable leadvar tailvar rowid
  (chr)    (int)   (dbl)   (dbl) (int)
1     a        0       1       0     1
2     a        1       0       1     2
3     b        0       1       0     5
4     b        1       0       1     6
5     c        0       1       0     9
6     d        1       0       1    10
5     d        1       0       1    11

要选择前导行和前导后的另外 2 行,您需要使用lag(lag(leadvar))代替。由于您需要根据需要嵌套尽可能多的延迟调用以获得所需的值,因此它可能不是最佳解决方案。

使用dplyr的更优雅的解决方案是使用group_bycumsum创建一个新列。所需要做的就是过滤leadvar是否为 1 或新列 ( csvar ) 是否具有您想要的n值。

dt %>% mutate(leadvar = ifelse(variable == 0 & lead(variable) == 1, 1, 0), 
              rowid = row_number()) %>%  group_by(id) %>% 
  mutate(csvar=cumsum(variable)) %>% filter(leadvar == 1 | csvar == 2)

这使:

     id variable leadvar rowid csvar
  (chr)    (int)   (dbl) (int) (int)
1     a        0       1     1     0
2     a        1       0     3     2
3     b        0       1     5     0
4     c        0       1     9     0
5     d        1       0    11     2

此解决方案仅适用于变量 == 1 的行,如果您想在领导者之后获得任何行,则必须创建一个填充为 1 的虚拟列,然后在其上创建group_bycumsum

于 2016-05-19T13:36:40.503 回答