我有以下数据框架结构:
id status
a 1
a 2
a 1
b 1
b 1
b 0
b 1
c 0
c 0
c 2
c 1
d 0
d 2
d 0
这里a,b,c是唯一的id,状态是0,1和2之间的标志。
我需要在整个时间范围内的任何一点选择状态从0变为1的每个个人ID,因此预期的输出将是两个id' b'和' c'。
我想过使用滞后来实现这一目标,但在那种情况下,我不能处理id' c,其中开头有一个0但是它达到了1某个阶段。关于如何使用窗口函数(或任何其他技术)实现此目的的任何想法
答案 0 :(得分:2)
您希望在状态为0后找到状态为1的ID。
这是一个dplyr解决方案:
library(dplyr)
# Generate data
mydf = data_frame(
id = c(rep("a", 3), rep("b", 4), rep("c", 4), rep("d", 3)),
status = c(1, 2, 1, 1, 1, 0, 1, 0, 0, 2, 1, 0, 2, 0)
)
mydf %>% group_by(id) %>%
# Keep only 0's and 1's
filter(status %in% c(0,1)) %>%
# Compute diff between two status
mutate(dif = status - lag(status, 1)) %>%
# If it is 1, it is a 0 => 1
filter(dif == 1) %>%
# Catch corresponding id's
select(id) %>%
unique
答案 1 :(得分:2)
使用dplyr
的一种可能方式(已修改仅在{/ 1}} 之后出现 id
1
}):
0
数据强>
library(dplyr)
df %>%
group_by(id) %>%
filter(status %in% c(0, 1)) %>%
filter(status == 0 & lead(status, default = 0) == 1) %>%
select(id) %>% unique()
#> # A tibble: 2 x 1
#> # Groups: id [2]
#> id
#> <chr>
#> 1 b
#> 2 c
答案 2 :(得分:1)
我不知道这是否是最有效的方式,但是:按id
分开,检查status
es 0
,如果有,请检查1
在0指数后面:
lst <- split(df$status, df$id)
f <- function(x) {
if (!any(x==0)) return(FALSE)
any(x[which.max(x==0):length(x)]==1)
}
names(lst)[(sapply(lst, f))]
# [1] "b" "c"