填补缺失的级别

msh*_*855 12 r missing-data

我有以下类型的数据帧:

Country <- rep(c("USA", "AUS", "GRC"),2)
Year    <- 2001:2006
Level   <- c("rich","middle","poor",rep(NA,3))
df <- data.frame(Country, Year,Level)

df 
Country Year  Level
1     USA 2001   rich
2     AUS 2002 middle
3     GRC 2003   poor
4     USA 2004   <NA>
5     AUS 2005   <NA>
6     GRC 2006   <NA>
Run Code Online (Sandbox Code Playgroud)

我想用右列中的最后一个用正确的级别标签填充缺失的值.

所以预期的结果应该是这样的:

Country Year  Level
1     USA 2001   rich
2     AUS 2002 middle
3     GRC 2003   poor
4     USA 2004   rich
5     AUS 2005 middle
6     GRC 2006   poor
Run Code Online (Sandbox Code Playgroud)

Ric*_*ven 12

在基数R中,您可以使用ave():

transform(df, Level = ave(Level, Country, FUN = na.omit))

#   Country Year  Level
# 1     USA 2001   rich
# 2     AUS 2002 middle
# 3     GRC 2003   poor
# 4     USA 2004   rich
# 5     AUS 2005 middle
# 6     GRC 2006   poor
Run Code Online (Sandbox Code Playgroud)

另一种更准确的可能性是使用连接.这里我们将Country列与NA省略的数据合并.结果是相同的,只是在不同的行顺序.

merge(df["Country"], na.omit(df))

#   Country Year  Level
# 1     AUS 2002 middle
# 2     AUS 2002 middle
# 3     GRC 2003   poor
# 4     GRC 2003   poor
# 5     USA 2001   rich
# 6     USA 2001   rich
Run Code Online (Sandbox Code Playgroud)


akr*_*run 10

我们可以按"国家/地区"进行分组,并获得非NA唯一值

library(dplyr)
df %>%
    group_by(Country) %>% 
    dplyr::mutate(Level = Level[!is.na(Level)][1])
# A tibble: 6 x 3
# Groups:   Country [3]
#  Country  Year  Level
#   <fctr> <int> <fctr>
#1     USA  2001   rich
#2     AUS  2002 middle
#3     GRC  2003   poor
#4     USA  2004   rich
#5     AUS  2005 middle
#6     GRC  2006   poor
Run Code Online (Sandbox Code Playgroud)

如果我们已经加载dplyr沿plyr,最好是明确指定dplyr::mutatedplyr::summarise以使它能够使用的功能从dplyr.它们具有相同的功能,plyr并且可能会在dplyr加载两者时创建不同的行为,从而掩盖这些功能.

  • 不错的想法.做得好.但是,我们不是在这里做出假设,总会有一个非独特的价值吗?只是想了解.. (3认同)

sam*_*dhi 8

你可以使用data.tablezoo: -

library(data.table)
library(zoo)
setDT(df)
df[, Level := na.locf(Level), by = Country]
Run Code Online (Sandbox Code Playgroud)

这会给你: -

   Country Year  Level
1:     USA 2001   rich
2:     AUS 2002 middle
3:     GRC 2003   poor
4:     USA 2004   rich
5:     AUS 2005 middle
6:     GRC 2006   poor
Run Code Online (Sandbox Code Playgroud)


eip*_*i10 5

library(dplyr)

df %>% 
  group_by(Country) %>% 
  mutate(Level = replace(Level, is.na(Level), unique(na.omit(Level))))
Run Code Online (Sandbox Code Playgroud)
  Country  Year  Level
   <fctr> <int> <fctr>
1     USA  2001   rich
2     AUS  2002 middle
3     GRC  2003   poor
4     USA  2004   rich
5     AUS  2005 middle
6     GRC  2006   poor
Run Code Online (Sandbox Code Playgroud)

或者,更简洁地应用@ suchait的想法na.locf:

df %>% 
  group_by(Country) %>% 
  mutate(Level = zoo::na.locf(Level))
Run Code Online (Sandbox Code Playgroud)