用平均值替换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)
我有一个包含缺失值数据列的数据框,我想通过使用上方和下方单元格的值取平均值来替换缺失值。
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)