簡體   English   中英

填寫R數據框中的缺失行

[英]Fill in missing rows in R data frame

我已經將一些原始數據導入到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. 建立一個新表(Table2),並從每個ID的最早年份到MODEL_YEAR連續幾年。
  3. 將Table1與Table2連接起來以重新添加這些值,並將所有NA值替換為零。

我認為我可以執行步驟1和3,但是還無法確定如何執行步驟2,即建立Table2。

如果您認為我的方法不是最佳方法,則可以提供任何幫助,也可以提供其他方法的建議。

謝謝

我認為tidyr::expand()會很有用。 這是一個tidyverse解決方案:

library(tidyverse)
# how to build table2
table2 <- table1 %>% group_by(ID) %>% mutate(Earliest.Year = min(Year)) %>%
        select(-Value, -Year) %>% distinct() %>%
        expand(Year = Earliest.Year:2015, Earliest.Year) %>%
        select(-Earliest.Year)

# a direct piepe solution
table1 %>% group_by(ID) %>% mutate(Earliest.Year = min(Year)) %>%
        select(-Value, -Year) %>% distinct() %>%
        expand(Year = Earliest.Year:2015, Earliest.Year) %>%
        select(-Earliest.Year) %>%
        left_join(table1, by = c("ID", "Year")) %>%
        replace(is.na(.), 0)
# output
# A tibble: 35 x 3
# Groups:   ID [?]
      ID  Year Value
   <int> <int> <dbl>
 1     1  1999    25
 2     1  2000    12
 3     1  2001     0
 4     1  2002    14
 5     1  2003     0
 6     1  2004     0
 7     1  2005     0
 8     1  2006     0
 9     1  2007     0
10     1  2008     0
# ... with 25 more rows

由於已經使用了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)Base R使用byID拆分table1 ,並將每個組件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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM