我经常遇到这样的情况,需要从另一个聚合级别的数据帧中提取值来替换数据帧中缺失的值。例如,如果我有一个包含县级数据的数据帧,我可能会使用存储在另一个数据帧中的州级值来替换NA值。在多次编写 merge
... ifelse(is.na())
等代码后,我决定编写一个函数来执行此操作。
这是我准备的函数和如何使用它的示例:
fillNaDf <- function(naDf, fillDf, mergeCols, fillCols){
mergedDf <- merge(naDf, fillDf, by=mergeCols)
for (col in fillCols){
colWithNas <- mergedDf[[paste(col, "x", sep=".")]]
colWithOutNas <- mergedDf[[paste(col, "y", sep=".")]]
k <- which( is.na( colWithNas ) )
colWithNas[k] <- colWithOutNas[k]
mergedDf[col] <- colWithNas
mergedDf[[paste(col, "x", sep=".")]] <- NULL
mergedDf[[paste(col, "y", sep=".")]] <- NULL
}
return(mergedDf)
}
## test case
fillDf <- data.frame(a = c(1,2,1,2), b = c(3,3,4,4) ,f = c(100,200, 300, 400), g = c(11, 12, 13, 14))
naDf <- data.frame( a = sample(c(1,2), 100, rep=TRUE), b = sample(c(3,4), 100, rep=TRUE), f = sample(c(0,NA), 100, rep=TRUE), g = sample(c(0,NA), 200, rep=TRUE) )
fillNaDf(naDf, fillDf, mergeCols=c("a","b"), fillCols=c("f","g") )
我成功解决了这个问题,但心里总觉得可能有人在我之前已经更优雅地解决了这个问题。是否有更好/更容易/更快的解决方案?此外,是否有一种方法可以消除函数中间的循环?该循环存在是因为我通常需要替换不止一个列中的NA值。是的,该函数假设我们需要填充的源列具有相同的名称,并且我们需要填充的目标列也是如此,合并操作同理。
任何指导或重构都将有所帮助。
编辑:12月2日,我发现我的示例中存在逻辑错误,已进行修复。
?data.table
的“示例”部分是典范,值得花大约20分钟来仔细研究。特别是如果你是一个大数据专家--而且看起来你可能是--这个前期时间投资真的非常值得。 - Josh O'Brienf:=i.f
和g:=i.g
吗? - rawr