Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何按数据框中的因素(按国家/地区划分)使用LOCF填充NAs_R_Dataframe_Missing Data_R Factor - Fatal编程技术网

R 如何按数据框中的因素(按国家/地区划分)使用LOCF填充NAs

R 如何按数据框中的因素(按国家/地区划分)使用LOCF填充NAs,r,dataframe,missing-data,r-factor,R,Dataframe,Missing Data,R Factor,我有以下数据框(简化),其中国家变量作为一个因子,值变量缺少值: 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")

我有以下数据框(简化),其中国家变量作为一个因子,值变量缺少值:

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))
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循环之前,我想知道是否有人知道如何解决这个问题


非常感谢

使用
by
拆分
data.frame
,并在子集上使用
na.locf

do.call(rbind,by(data,data$country,na.locf))
如果要删除行名称,请执行以下操作:

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

这里有一个
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(DF, "country", na.locf)
ddply(DF, ~country, na.locf)
请注意,不允许将
.variables
替换为
DF$variable
,这就是执行此操作时出错的原因


DF
是您的数据。frame

如果需要考虑速度,则此
取消堆栈
/
堆栈
解决方案的速度大约是我系统上其他解决方案的4到6倍,尽管它确实需要稍长的代码行:

stack(lapply(unstack(data, value ~ country), na.locf, na.rm = FALSE))
另一种方法是:

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

您只需按国家划分,然后a进行a或na填充,填充到右侧。 下面是一个显式显示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
库(plyr)
图书馆(动物园)

数据现代版本的
ddply
解决方案是使用包
dplyr

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

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

我这次谈话有点晚了,但这里有一个
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)

dplyrimputet的组合可以完成这项工作

library(dplyr)
library(imputeTS)
data %>% group_by(country) %>% 
mutate(value = na.locf(value, na.remaining="keep"))   
使用na.locf函数的na.remaining参数inputets,您还可以选择如何处理后续NAs

这些是选项:

  • “保留”-返回带有NAs的系列
  • “rm”-删除剩余的NAs
  • “平均值”-用总体平均值替换剩余的NAs
  • “rev”-从相反方向执行nocb/locf

例如,通过选择“平均值”,您将得到特定示例中每个GER的结果为7。

如果您将问题编辑为包含合理的测试数据结构,您可能会得到更快的响应。您想要!太棒了,谢谢!正是我需要的。我以前尝试过
ddply
,使用
ddply(DF,DF$country,na.locf)
,但没有成功。使用
()
符号有什么区别?谢谢,这也行。但是,我必须再次将行名称重命名为
seq_len(nrow(data))
。因此,我选择了上述答案。但是,您的解决方案在计算上可能会更快,因为
ddply
对于大数据集来说似乎非常慢。@Gregor,所以OP也想按国家进行划分,我错过了这一点,
na.locf
提到的,它们被隐藏在第三段中。现在效果很好。通常标题和第一段应该说明问题,我不明白你为什么不把它们修好,我只是现在修好了。在过去的1.5年里,你们中的任何人都可以而且应该纠正这一点。您现在可以删除您的否决票。dplyr版本为+1@Gregor,请注意,您需要将
na.rm=F
添加到
na.locf()
调用中。否则会引发错误。有没有办法一次对多个列执行此操作?@RafaelMartins请参见
?mutate\u at
library(dplyr)
library(imputeTS)
data %>% group_by(country) %>% 
mutate(value = na.locf(value, na.remaining="keep"))