如何用数据框中的因子用LOCF填充NA,按国家/地区划分

rp1*_*rp1 18 r missing-data dataframe r-factor

我有以下数据框(简化),国家/地区变量作为因素,值变量具有缺失值:

country value
AUT     NA
AUT     5
AUT     NA
AUT     NA
GER     NA
GER     NA
GER     7
GER     NA
GER     NA
Run Code Online (Sandbox Code Playgroud)

以下内容生成以上数据框:

data <- data.frame(country=c("AUT", "AUT", "AUT", "AUT", "GER", "GER", "GER", "GER", "GER"), value=c(NA, 5, NA, NA, NA, NA, 7, NA, NA))
Run Code Online (Sandbox Code Playgroud)

现在,我想使用最后一次观察结果(LOCF)替换每个国家子集中的NA值.我知道命令na.locf动物园包.data <- na.locf(data)会给我以下数据框:

country value
AUT     NA
AUT     5
AUT     5
AUT     5
GER     5
GER     5
GER     7
GER     7
GER     7
Run Code Online (Sandbox Code Playgroud)

但是,该功能仅应用于按国家/地区划分的各个子集.以下是我需要的输出:

country value
AUT     NA
AUT     5
AUT     5
AUT     5
GER     NA
GER     NA
GER     7
GER     7
GER     7
Run Code Online (Sandbox Code Playgroud)

我想不出一个简单的方法来实现它.在开始使用for循环之前,我想知道是否有人知道如何解决这个问题.

非常感谢!!

Gre*_*gor 15

ddply解决方案的现代版本是使用该包dplyr:

library(dplyr)
DF %>%
  group_by(county) %>% 
  mutate(value = na.locf(value, na.rm = F))      
Run Code Online (Sandbox Code Playgroud)

  • dplyr 版本+1。@Gregor,请注意,您需要将“na.rm = F”添加到“na.locf()”调用中。否则这会引发错误。 (2认同)

Jil*_*ina 13

这是一个ddply解决方案.试试这个

library(plyr)
ddply(DF, .(country), na.locf)
  country value
1     AUT  <NA>
2     AUT     5
3     AUT     5
4     AUT     5
5     GER  <NA>
6     GER  <NA>
7     GER     7
8     GER     7
9     GER     7
Run Code Online (Sandbox Code Playgroud)

编辑ddply帮助您可以找到它

.variables:  variables to split data frame by, 
as quoted variables, a formula or character vector.
Run Code Online (Sandbox Code Playgroud)

得到你想要的另一种选择是:

ddply(DF, "country", na.locf)
ddply(DF, ~country, na.locf)
Run Code Online (Sandbox Code Playgroud)

注意,替换.variablesDF$variable是不允许的,这就是为什么你这样做的时候得到一个错误.

DF 是你的data.frame


小智 8

虽然不使用locf,但整齐的方式是:

library(tidyverse)

data %>% 
    group_by(country) %>% 
    fill(value)

Source: local data frame [9 x 2]
Groups: country [2]

country value
(fctr) (dbl)
1     AUT    NA
2     AUT     5
3     AUT     5
4     AUT     5
5     GER    NA
6     GER    NA
7     GER     7
8     GER     7
9     GER     7
Run Code Online (Sandbox Code Playgroud)


nog*_*pes 6

拆分data.framewith byna.locf在子集上使用:

do.call(rbind,by(data,data$country,na.locf))
Run Code Online (Sandbox Code Playgroud)

如果要删除行名称:

do.call(rbind,unname(by(data,data$country,na.locf)))
Run Code Online (Sandbox Code Playgroud)