我与国家变量作为因子和变量的值以下的数据帧(简化的)已经缺失值:
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)
注意更换.variables
与DF$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.frame
与by
和使用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:
包的组合dplyr和imputeTS可以做的工作。
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