我有一个数据帧,我想通过仅选择连续值“1”来对其进行子集化。
具体来说,我有一个如下所示的数据框:
library(tidyverse)
library(zoo)
df <- data.frame(matrix(ncol = 3, nrow = 16))
colnames(df) <- c("row_id","id", "k_yes")
df$row_id <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
df$id <- c("1_1","1_1","1_1","1_1","1_1","1_2","1_2","1_2","1_2","1_2","1_2","1_3","1_3","1_3","1_3","1_3")
df$k_yes <- c(1,1,1,0,1,0,0,0,1,1,0,1,0,1,0,1)
df
row_id id k_yes
1 1 1_1 1
2 2 1_1 1
3 3 1_1 1
4 4 1_1 0
5 5 1_1 1
6 6 1_2 0
7 7 1_2 0
8 8 1_2 0
9 9 1_2 1
10 10 1_2 1
11 11 1_2 0
12 12 1_3 1
13 13 1_3 0
14 14 1_3 1
15 15 1_3 0
16 16 1_3 1
我想创建两个数据集:
1) 每组 (
id
) 仅包含“1”,但始终有两个或多个连续的。所以,如果两个“1”之间有一个“0”,至少最后一个“1”应该被丢弃。所以它会接受像这样的序列1-1
、 1-1-1
等,但不是 0-1-1
或 1-1-1-0
这个数据框看起来像这样:
row_id id k_yes
1 1 1_1 1
2 2 1_1 1
3 3 1_1 1
4 9 1_2 1
5 10 1_2 1
2) 另一种,每组 (
id
) 接受“1”之间的一个“0”,但如果“0”之后没有其他“1”,则不接受。
所以它会接受像这样的序列1-0-1
、1-1-0-1
、1-1-0-1-1
、1-1-0-1-0-1
等,但不包括像0-1-1
或1-1-0
或1-1-0-0-1
这样的序列(在后面,它只会保留前一个1)。
df 所需的输出是:
row_id id k_yes
1 1 1_1 1
2 2 1_1 1
3 3 1_1 1
4 4 1_1 0
5 5 1_1 1
6 9 1_2 1
7 10 1_2 1
8 12 1_3 1
9 13 1_3 0
10 14 1_3 1
11 15 1_3 0
12 16 1_3 1
我尝试遵循这个答案,但它没有成功,正如我所尝试的:
> df |>
group_by(id) |>
mutate(b = c(first(k_yes) , zoo::rollsum(k_yes, 1))) |>
summarise(groups_to_keep = id[which(b >= 2)]) -> gk
Error in `mutate()`:
ℹ In argument: `b = c(first(k_yes), zoo::rollsum(k_yes, 1))`.
ℹ In group 1: `id = "1_1"`.
Caused by error:
! `b` must be size 5 or 1, not 6.
我认为问题出在
rollsum()
函数上,但是在检查了帮助页面后,我仍然不清楚这个函数应该如何应用。
如有任何帮助,我们将不胜感激!
filter(df, k_yes & (lag(k_yes) | lead(k_yes)), .by = id)