如何通过在数据帧的因素,以填补LOCF来港,因国家分裂(How to fill NAs with L

2019-07-04 06:15发布

我与国家变量作为因子和变量的值以下的数据帧(简化的)已经缺失值:

country value
AUT     NA
AUT     5
AUT     NA
AUT     NA
GER     NA
GER     NA
GER     7
GER     NA
GER     NA

下面的命令生成上述数据帧:

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))

现在,我想用最后一次观察结转(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

但是, 该功能只应在该国分裂个别子使用 。 以下是输出我需要:

country value
AUT     NA
AUT     5
AUT     5
AUT     5
GER     NA
GER     NA
GER     7
GER     7
GER     7

我想不出来实现它的简单方法。 与开始for循环之前,我想知道如果任何人有任何想法,如何解决这个问题。

非常感谢!!

Answer 1:

这里有一个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

编辑ddply帮助,您可以发现,

.variables:  variables to split data frame by, 
as quoted variables, a formula or character vector.

所以另一种替代方案得到你想要的是什么:

ddply(DF, "country", na.locf)
ddply(DF, ~country, na.locf)

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

DF是你的data.frame



Answer 2:

在一个现代版的ddply的解决方案是使用包dplyr

library(dplyr)
DF %>%
  group_by(county) %>% 
  mutate(value = na.locf(value, na.rm = F))      


Answer 3:

在tidyverse方式,虽然没有使用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


Answer 4:

拆分data.frameby和使用na.locf的子集:

do.call(rbind,by(data,data$country,na.locf))

如果你想删除的行名称:

do.call(rbind,unname(by(data,data$country,na.locf)))


Answer 5:

您只需按国家分裂,然后做任何一个动物园:: na.locf()或na.fill,填充到右边。 这里是明确地示出na.fill的三组分ARG语法的例子:

library(plyr)
library(zoo)

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))

# The following is equivalent to na.locf
na.fill.right <- function(...) { na.fill(..., list(left=NA,interior=NA,right="extend")) }

ddply(data, .(country), na.fill.right)

  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


Answer 6:

如果速度是一个考虑因素则该unstack / stack溶液比我的系统上的其他人快约4到6倍,尽管它不意味着代码稍长的线路:

stack(lapply(unstack(data, value ~ country), na.locf, na.rm = FALSE))

另一种方法是:

transform(data, value = ave(value, country, FUN = na.locf0))


Answer 7:

我有点晚了这次谈话,但这里是一个data.table的方式,这将是更快更大的数据集:

library(zoo)
library(data.table)

# Convert to data table
setDT(data)

data[, value := na.locf(value, na.rm = FALSE), by = country]

data
   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

# And if you want to convert "data" back to a data frame...
setDF(data)


Answer 8:

包的组合dplyrimputeTS可以做的工作。

library(dplyr)
library(imputeTS)
data %>% group_by(country) %>% 
mutate(value = na.locf(value, na.remaining="keep"))   

随着imputeTS的na.locf功能的na.remaining参数你有另外的选择,如何处理尾随来港做选择。

这些选项:

  • “养” - 返回的NAS系列
  • “RM” - 去除残留的NA
  • “意味着” - 取代的总平均剩余的NA
  • “REV” - 执行nocb /从相反方向LOCF

通过选择“的意思是”你会如得到的结果与7,每GER的具体例子。



文章来源: How to fill NAs with LOCF by factors in data frame, split by country