r语言 - 对于每个单独的id,过滤在year列中具有连续值的行



我想从下面的数据框创建一个平衡的面板数据:

id  program_year  value
1     2007         1
1     2008         1
1     2009         1
1     2010         1
1     2011         1
1     2012         1
1     2013         0
2     2007         0
2     2008         1
2     2009         1
2     2010         1
2     2011         1  
2     2012         1
2     2013         1
3     2007         1
3     2008         0
3     2009         1
3     2010         1
3     2011         1
3     2012         1
3     2013         1

对于每个id,我要选择5行,这些行具有连续的value == 1program_year

预期的输出应该如下所示:

id  program_year  value
1     2007         1
1     2008         1
1     2009         1
1     2010         1
1     2011         1
2     2008         1
2     2009         1
2     2010         1
2     2011         1  
2     2012         1
3     2009         1
3     2010         1
3     2011         1
3     2012         1
3     2013         1

我已经探索了lead()lag(),但没有任何成功。获得所需输出后的下一步是索引年份,使数据帧成为一个平衡的面板。

不确定这是否是您需要的:

Data <- "id  program_year  value
1     2007         1
1     2008         1
1     2009         1
1     2010         1
1     2011         1
1     2012         1
1     2013         0
2     2007         0
2     2008         1
2     2009         1
2     2010         1
2     2011         1  
2     2012         1
2     2013         1
3     2007         1
3     2008         0
3     2009         1
3     2010         1
3     2011         1
3     2012         1
3     2013         1"
DF <- read.table(text = Data, header = TRUE)

library(dplyr)
DF %>%
arrange(id, program_year) %>%
group_by(id) %>%
filter((program_year - lag(program_year)) >= 1) %>% 
mutate(consecutive = program_year - row_number()) %>%
group_by(id, consecutive) %>%
filter(n() >= 5) %>%
slice_head(n = 5) %>%
ungroup() %>%
filter(value == 1) %>%
select(id, program_year, value)

返回以下内容:

# A tibble: 14 × 3
id program_year value

<int>        <int> <int>
1     1         2008     1
2     1         2009     1
3     1         2010     1
4     1         2011     1
5     1         2012     1
6     2         2008     1
7     2         2009     1
8     2         2010     1
9     2         2011     1
10     2         2012     1
11     3         2009     1
12     3         2010     1
13     3         2011     1
14     3         2012     1

修改答案以满足您的条件where value == 1

下面是使用dplyr::consecutive_id()和每个操作分组的解决方案。请确保您使用的是最新版本的dplyr。

library(dplyr) # >= v1.1.0
dat %>%
mutate(c_id = consecutive_id(value), .by = id) %>%
filter(value == 1, n() >= 5, .by = c(id, c_id)) %>%
filter(row_number() <= 5, .by = id) %>%
select(!c_id)
id program_year value
1   1         2007     1
2   1         2008     1
3   1         2009     1
4   1         2010     1
5   1         2011     1
6   2         2008     1
7   2         2009     1
8   2         2010     1
9   2         2011     1
10  2         2012     1
11  3         2009     1
12  3         2010     1
13  3         2011     1
14  3         2012     1
15  3         2013     1

这里的技巧是创建两个虚拟列:首先是行号列,然后是按列分组的虚拟列。最后,从结果中取消选择虚拟列。

df %祝辞% group_by (id) %祝辞%安排(program_year) %祝辞%过滤器(价值! = 0)%祝辞%变异(row_num = row_number (), dummygroup = program_year-row_num) %祝辞% group_by (id、dummygroup) %祝辞%安排(id、desc (program_year)) %祝辞%过滤器(n()在= 5,row_number () & lt; = 5)

by中,对于每个ID,我们可以首先为非零值创建subset,为连续值集创建u组,为table中产生which.max个数的组创建subsetx组。接下来我们head类列表"by"对象为min的最大观测次数,最后rbind

by(dat, dat$id, (x) {
x <- subset(x, x$value == 1)
u <- cumsum(c(1, diff(x$program_year)) != 1) + 1
tbl <- table(u)
subset(x, u == which.max(tbl))
}) |> {(.) lapply(., (x) {
m <- min(sapply(., nrow))
transform(head(x, m), period=seq_len(m))
})}() |>  ## or `tail` instead of `head`
do.call(what='rbind')
#      id program_year value period
# 1.1   1         2007     1      1
# 1.2   1         2008     1      2
# 1.3   1         2009     1      3
# 1.4   1         2010     1      4
# 1.5   1         2011     1      5
# 2.9   2         2008     1      1
# 2.10  2         2009     1      2
# 2.11  2         2010     1      3
# 2.12  2         2011     1      4
# 2.13  2         2012     1      5
# 3.17  3         2009     1      1
# 3.18  3         2010     1      2
# 3.19  3         2011     1      3
# 3.20  3         2012     1      4
# 3.21  3         2013     1      5

给出给定id的连续观测的最大可能子集,尽管在OP中要求不匹配年,但增加了一个新的周期变量。


数据:

dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), program_year = c(2007L, 
2008L, 2009L, 2010L, 2011L, 2012L, 2013L, 2007L, 2008L, 2009L, 
2010L, 2011L, 2012L, 2013L, 2007L, 2008L, 2009L, 2010L, 2011L, 
2012L, 2013L), value = c(1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
-21L))

最新更新