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::completetidyr::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