用平均值替换R中的缺失值

replacing a missing value in R with average value

我有一个包含缺失值数据列的数据框,我想通过使用上方和下方单元格的值取平均值来替换缺失值。

 df1<-c(2,2,NA,10, 20, NA,3)
 if(df1[i]== NA){
 df1[i]= mean(df1[i+1],df1[i-1])
}

但是,我遇到了这个错误

  Error in if (df1[i] == NA) { : missing value where TRUE/FALSE needed
  In addition: Warning message:
  In if (df1[i] == NA) { :
  the condition has length > 1 and only the first element will be used

如果有任何指导可以解决此问题,我们将不胜感激。

检查 NA 使用 is.na(),创建一个循环并给 mean() 一个向量作为参数,否则它只会看到第一个值。如果您没有连续的 NA 并且第一个和最后一个条目是非 NA,这应该有效:

df1<-c(2,2,NA,10, 20, NA,3)
for(i in 2:(length(df1)-1)){
  if(is.na(df1[i])){
     df1[i]= mean(c(df1[i+1],df1[i-1]))
  }
}

如果您确定没有任何连续的 NA 值并且第一个和最后一个元素永远不是 NA,那么您可以这样做

df1<-c(2,2,NA,10, 20, NA,3)
idx<-which(is.na(df1))
df1[idx] <- (df1[idx-1] + df1[idx+1])/2
df1
# [1]  2.0  2.0  6.0 10.0 20.0 11.5  3.0

这应该比循环更有效。

使用来自 dplyr 的滞后和超前:

library(dplyr)

df1[is.na(df1)] <- (df1[is.na(lag(df1, default=""))] +          
                    df1[is.na(lead(df1, default=""))]) / 2

这将比 for 循环版本快得多

您可以使用 zoo 包中的 na.approx()NA 替换为插值:

library(zoo)
> na.approx(df1)
# [1]  2.0  2.0  6.0 10.0 20.0 11.5  3.0

如@G.Grothendieck所述,如果连续有多个NA,这将填充NA。此外,如果末尾可以有 NA,那么添加参数 na.rm = FALSE 将保留它们,或者添加 rule = 2 将用第一个或最后一个非 NA 替换它们。

它首先检查相应列中的 NA,如果有缺失值,它会用列的平均值替换,否则只是 returns 数据集。

df$col_name <- ifelse(is.na(df$col_name), ave(df$col_name, Fun = function(x) mean(x, na.rm ==TRUE)),df$col_name)