R:有没有办法插入完成年份序列的行?
R: Is there a way to insert rows that complete a year sequence?
我正在使用有关个人的纵向数据库(注册数据非常大)处理 R,每个 ID 有几行(在数据库中名为“vn”)及其列中的属性。我的变量“观察”表示每年的观察。有时(但并非在所有情况下)会跳过一年或多年,因为对个人而言没有任何变化。我想将那些“缺失的行”添加到我的数据库中,以便每个人在第一次和最后一次观察之间的每一年都有一个条目(每个人不一定都相同)。由于个人的属性会随时间变化,因此添加的行必须包含与前一行相同的属性值(对于下面的示例,如果为 2010 年添加一行,则个人的婚姻状况值为 3,市政当局值为 5584) .
这是我数据库中个人的概览:
structure(list(vn = c("555", "555", "555", "555", "555", "555", "555", "555", "555", "555", "555"), municipality = c(5586, 5586, 5586, 5586, 5586, 5586, 5611, 5611, 5584, 5584, 5584), yearofbirth = c(1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957), sex = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), maritalstatus = c(2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), observation = c(2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012)), row.names = 470:480, class = "data.frame")
我当前的代码(如下)在缺少观察年时向我的数据集添加行,保留前一行的所有信息,除了现在,一些信息加倍,一些观察年出现两次。
test<-test %>% expand(vn, municipality, yearofbirth, sex, maritalstatus, full_seq(observation,1))
我也在考虑使用 rep()
,但找不到方法来做我想做的事。
有没有人知道可以帮助我的代码?
如果我们每年至少进行一次观察,那么可以通过 tidyr::complete
和 tidyr::fill
来实现,如下所示:
编辑 1:如果不是所有年份都出现在数据集中,该方法仍然有效,首先将 observation
转换为 factor
,并将级别设置为年份范围:
编辑 2:要考虑到不同的年份范围,必须在填充后进行过滤。为此,我添加了一个变量 last_obs,其中包含对某个人观察到的最后一年。该变量可用于填充后过滤
<!-- language-all: lang-r -->
d <- structure(list(vn = c("555", "555", "555", "555", "555", "555", "555", "555", "555", "555", "555"), municipality = c(5586, 5586, 5586, 5586, 5586, 5586, 5611, 5611, 5584, 5584, 5584), yearofbirth = c(1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957), sex = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), maritalstatus = c(2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), observation = c(2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012)), row.names = 470:480, class = "data.frame")
library(dplyr)
library(tidyr)
# Add some data
d1 <- d %>%
mutate(vn = "556") %>%
filter(observation <= 2010, observation %% 2 == 0)
# Bind data
d2 <- bind_rows(d, d1)
d2 %>%
# Add year of last obs by vn
group_by(vn) %>%
mutate(last_obs = last(observation)) %>%
ungroup() %>%
# Convert to fct
mutate(observation = factor(observation, levels = 2000:2016)) %>%
# Complete and fill
tidyr::complete(vn, observation) %>%
tidyr::fill(everything()) %>%
# Convert back to numeric
mutate(observation = as.integer(as.character(observation))) %>%
# Drop obs after year of last obs
filter(as.numeric(observation) <= last_obs) %>%
# Drop helper
select(-last_obs)
#> # A tibble: 22 x 6
#> vn observation municipality yearofbirth sex maritalstatus
#> <chr> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 555 2000 5586 1957 2 2
#> 2 555 2001 5586 1957 2 2
#> 3 555 2002 5586 1957 2 3
#> 4 555 2003 5586 1957 2 3
#> 5 555 2004 5586 1957 2 3
#> 6 555 2005 5586 1957 2 3
#> 7 555 2006 5611 1957 2 3
#> 8 555 2007 5611 1957 2 3
#> 9 555 2008 5584 1957 2 3
#> 10 555 2009 5584 1957 2 3
#> # ... with 12 more rows
我正在使用有关个人的纵向数据库(注册数据非常大)处理 R,每个 ID 有几行(在数据库中名为“vn”)及其列中的属性。我的变量“观察”表示每年的观察。有时(但并非在所有情况下)会跳过一年或多年,因为对个人而言没有任何变化。我想将那些“缺失的行”添加到我的数据库中,以便每个人在第一次和最后一次观察之间的每一年都有一个条目(每个人不一定都相同)。由于个人的属性会随时间变化,因此添加的行必须包含与前一行相同的属性值(对于下面的示例,如果为 2010 年添加一行,则个人的婚姻状况值为 3,市政当局值为 5584) .
这是我数据库中个人的概览:
structure(list(vn = c("555", "555", "555", "555", "555", "555", "555", "555", "555", "555", "555"), municipality = c(5586, 5586, 5586, 5586, 5586, 5586, 5611, 5611, 5584, 5584, 5584), yearofbirth = c(1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957), sex = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), maritalstatus = c(2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), observation = c(2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012)), row.names = 470:480, class = "data.frame")
我当前的代码(如下)在缺少观察年时向我的数据集添加行,保留前一行的所有信息,除了现在,一些信息加倍,一些观察年出现两次。
test<-test %>% expand(vn, municipality, yearofbirth, sex, maritalstatus, full_seq(observation,1))
我也在考虑使用 rep()
,但找不到方法来做我想做的事。
有没有人知道可以帮助我的代码?
如果我们每年至少进行一次观察,那么可以通过 tidyr::complete
和 tidyr::fill
来实现,如下所示:
编辑 1:如果不是所有年份都出现在数据集中,该方法仍然有效,首先将 observation
转换为 factor
,并将级别设置为年份范围:
编辑 2:要考虑到不同的年份范围,必须在填充后进行过滤。为此,我添加了一个变量 last_obs,其中包含对某个人观察到的最后一年。该变量可用于填充后过滤
<!-- language-all: lang-r -->
d <- structure(list(vn = c("555", "555", "555", "555", "555", "555", "555", "555", "555", "555", "555"), municipality = c(5586, 5586, 5586, 5586, 5586, 5586, 5611, 5611, 5584, 5584, 5584), yearofbirth = c(1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957), sex = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), maritalstatus = c(2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), observation = c(2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012)), row.names = 470:480, class = "data.frame")
library(dplyr)
library(tidyr)
# Add some data
d1 <- d %>%
mutate(vn = "556") %>%
filter(observation <= 2010, observation %% 2 == 0)
# Bind data
d2 <- bind_rows(d, d1)
d2 %>%
# Add year of last obs by vn
group_by(vn) %>%
mutate(last_obs = last(observation)) %>%
ungroup() %>%
# Convert to fct
mutate(observation = factor(observation, levels = 2000:2016)) %>%
# Complete and fill
tidyr::complete(vn, observation) %>%
tidyr::fill(everything()) %>%
# Convert back to numeric
mutate(observation = as.integer(as.character(observation))) %>%
# Drop obs after year of last obs
filter(as.numeric(observation) <= last_obs) %>%
# Drop helper
select(-last_obs)
#> # A tibble: 22 x 6
#> vn observation municipality yearofbirth sex maritalstatus
#> <chr> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 555 2000 5586 1957 2 2
#> 2 555 2001 5586 1957 2 2
#> 3 555 2002 5586 1957 2 3
#> 4 555 2003 5586 1957 2 3
#> 5 555 2004 5586 1957 2 3
#> 6 555 2005 5586 1957 2 3
#> 7 555 2006 5611 1957 2 3
#> 8 555 2007 5611 1957 2 3
#> 9 555 2008 5584 1957 2 3
#> 10 555 2009 5584 1957 2 3
#> # ... with 12 more rows