如何在R

时间:2017-12-01 10:30:33

标签: r dplyr window-functions

我有以下数据框架结构:

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某个阶段。关于如何使用窗口函数(或任何其他技术)实现此目的的任何想法

3 个答案:

答案 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"