在没有 For 循环的情况下替换或输入 R 中的 NA 值

Replacing or imputing NA values in R without For Loop

是否有更好的方法来处理数据框中的观察结果并估算 NA 值?我把一个 'for loop' 放在一起似乎可以完成这项工作,将 NA 与行的平均值交换,但我想知道是否有更好的方法不使用 for 循环来解决这个问题 -也许是一个内置的 R 函数?

# 1. Create data frame with some NA values. 

rdata <- rbinom(30,5,prob=0.5)
rdata[rdata == 0] <- NA
mtx <- matrix(rdata, 3, 10)
df <- as.data.frame(mtx)  
df2 <- df

# 2. Run for loop to replace NAs with that row's mean.

for(i in 1:3){            # for every row
x <- as.numeric(df[i,])   # subset/extract that row into a numeric vector
y <- is.na(x)             # create logical vector of NAs
z <- !is.na(x)            # create logical vector of non-NAs
result <- mean(x[z])      # get the mean value of the row 
df2[i,y] <- result        # replace NAs in that row
}

# 3. Show output with imputed row mean values.

print(df)  # before
print(df2) # after 

一种可能性,使用 Hmisc 中的 impute,它允许选择任何函数进行插补,

library(Hmisc)
t(sapply(split(df2, row(df2)), impute, fun=mean))

此外,您可以隐藏 apply

中的循环
t(apply(df2, 1, function(x) {
    mu <- mean(x, na.rm=T)
    x[is.na(x)] <- mu
    x
}))

数据:

set.seed(102)
rdata <- matrix(rbinom(30,5,prob=0.5),nrow=3)
rdata[cbind(1:3,2:4)] <- NA
df <- as.data.frame(rdata)

这比我想要的要复杂一些——它依赖于 R 中矩阵的列主排序以及行均值向量循环到矩阵的全长。我试图想出一个 sweep() 解决方案,但到目前为止没有成功。

rmeans <- rowMeans(df,na.rm=TRUE)
df[] <- ifelse(is.na(df),rmeans,as.matrix(df))

这是一种可能的矢量化方法(没有任何循环)

indx <- which(is.na(df), arr.ind = TRUE)
df[indx] <- rowMeans(df, na.rm = TRUE)[indx[,"row"]]

一些解释

我们可以使用 which 中的 arr.ind 参数来识别 NA 的位置。然后我们可以简单地索引 df (通过行和列索引)和行均值(仅通过行索引)并相应地替换值