我想简单地选择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
1}}如果1
前面有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))
答案 0 :(得分:1)
使用 dplyr 有一些解决这个问题的方法,第一个涉及创建一个额外的变量( tailvar )以捕获两个变量 leadvar 是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_by 和 cumsum 创建新列。如果 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_by 和 cumsum 就是这样。