根据您的评论,向量num_var 不是从数据框的第一列开始并且不连续,那么您需要这个
# simple example with just four columns
allProspect.tst <- data.frame(one=c(1:3,8), two=c(NA,4:6), three=1:4, four= c(5,NA,7, 8))
# want to replace NAs in columns "two" and "four" with values 5 and 7, respectively
num_var <- c("two","four")
median.to.replace <- c(5, 7)
# let's see the data before replacement
print(allProspect.tst)
## one two three four
##1 1 NA 1 5
##2 2 4 2 NA
##3 3 5 3 7
##4 8 6 4 8
# just loop over the collection of column names (not indices)
for (name_col in num_var) {
na_rows <- is.na(allProspect.tst[,name_col])
# key is to get the corresponding element in median.to.replace
# using which() index in num_var has value equal name_col
allProspect.tst[na_rows,name_col] <- median.to.replace[which(num_var==name_col)]
}
# now let's see the replaced data
print(allProspect.tst)
## one two three four
##1 1 5 1 5
##2 2 4 2 7
##3 3 5 3 7
##4 8 6 4 8
更新:提高效率
有很多方法可以使大量列的替换操作更有效,但最基本的使用 *apply 系列函数 look here for an excellent overview,来自 R base 包。更新后的代码如下:
replace.with.median <- function(col, median.val, df) {
na_rows <- is.na(df[, col])
df[na_rows, col] <- median.val
return(df[, col])
}
allProspect.tst[, num_var] <- mapply(replace.with.median, num_var, median.to.replace,
MoreArgs=list(df=allProspect.tst))
print(allProspect.tst)
## one two three four
##1 1 5 1 5
##2 2 4 2 7
##3 3 5 3 7
##4 8 6 4 8
注意事项:
-
原来的for循环体被封装在函数replace.with.median中。输入参数是:
-
col:要查找NAs 替换的列名
-
median.val:来自median.to.replace的对应替换值
-
df: 包含数据的数据框
此函数从df 返回col 列,其NAs 被替换为median.val。
-
使用mapply,根据上面的链接:
当您有多个数据结构(例如向量、列表)并且您希望将函数应用于每个数据结构的第一个元素,然后每个元素的第二个元素等时,
在这里,我们希望将函数replace.with.median 应用于两个向量num_var 和median.to.replace 以“锁步”方式相互关联。另外,我们通过mapply的MoreArgs参数提供allProspect.tst到replace.with.median的数据框。
- 从
mapply 返回的是已替换NAs 的列向量的集合。然后我们用这些替换allProspect.tst 的相应列。
希望这会有所帮助。