填写R数据框中的缺失行

时间:2019-03-08 13:35:55

标签: r data-manipulation

我已经将一些原始数据导入到R中,如下所示:

表1:

ID    Year    Value
01    1999       25
01    2000       12
01    2002       14
02    1998       16
02    2003        0
02    2004       14

该表按ID和Year排序,但是如您所见,缺少某些年份。我从数据来源知道,这些缺失年份的价值应该为零。我有另一个变量,我将其称为MODEL_YEAR,并将其设置为2015年。我想填补空白,直到并包括MODEL_YEAR。

我认为我应该采取的步骤是:

  1. 在表1中为每个ID选择最早的年份。
  2. 建立一个新表(表2),从每个ID的最早年份到MODEL_YEAR都具有连续的年份。
  3. 将Table1插入Table2以重新添加值,并将所有NA值替换为零。

我认为我可以执行第1步和第3步,但是还无法弄清楚如何执行第2步(构建Table2)。

如果您认为我的方法不是最佳方法,将对您有所帮助,或者提供其他替代方法的建议。

谢谢

2 个答案:

答案 0 :(得分:2)

由于已经使用tidyr::expand(),因此tidyr::complete的解决方案略有不同:

library(tidyverse)

dat %>%
  bind_rows(
    mutate(dat, Year = 2015, Value = 0) %>% unique()
  ) %>%
  group_by(ID) %>%                           # allows to start from earliest year
  complete(Year = full_seq(Year, 1), ID) %>% # expand years up 2 2015 for each ID
  mutate(Value = coalesce(Value, 0)) %>%     # fill NAs by zeros
  ungroup()  

哪个输出:

# A tibble: 35 x 3
    Year ID    Value
   <dbl> <chr> <dbl>
 1  1999 01       25
 2  2000 01       12
 3  2001 01        0
 4  2002 01       14
 5  2003 01        0
 6  2004 01        0
 7  2005 01        0
 8  2006 01        0
 9  2007 01        0
10  2008 01        0
# ... with 25 more rows

我使用的数据:

dat <- read.table(
  text = "ID    Year    Value
          01    1999       25
          01    2000       12
          01    2002       14
          02    1998       16
          02    2003        0
          02    2004       14",
  header = T,
  colClasses = c("character", "integer", "integer")
)

答案 1 :(得分:1)

1)基数R 使用bytable1除以ID,对于每个分量rbind,将其拆分为具有相同元素的数据帧ID,每个期望的YearValue都为0。然后使用sum对其进行汇总,最后使用rbind将组件重新组合在一起。

do.call("rbind", by(table1, table1$ID, function(x) {
  r <- rbind(x, data.frame(ID = x$ID[1], Year = x$Year[1]:MODEL_YEAR, Value = 0))
  aggregate(Value ~ ID + Year, r, sum)
}))

给予:

     ID Year Value
1.1   1 1999    25
1.2   1 2000    12
1.3   1 2001     0
1.4   1 2002    14
1.5   1 2003     0
1.6   1 2004     0
1.7   1 2005     0
...etc...

2)dplyr :使用相同的方法,但被翻译为使用dplyr。

library(dplyr)

table1 %>%
 group_by(ID) %>%
 do(bind_rows(., data.frame(ID = .$ID[1], Year = .$Year[1]:MODEL_YEAR, Value = 0))) %>%
 group_by(Year, add = TRUE) %>%
 summarize(Value = sum(Value)) %>%
 ungroup

注意

table1是可复制的形式:

table1 <-
structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 2L), Year = c(1999L, 
2000L, 2002L, 1998L, 2003L, 2004L), Value = c(25L, 12L, 14L, 
16L, 0L, 14L)), class = "data.frame", row.names = c(NA, -6L))

MODEL_YEAR <- 2015