У меня регулярно возникают ситуации, когда мне нужно заменить отсутствующие значения из data.frame значениями из какого-то другого data.frame, который находится на другом уровне агрегации. Так, например, если у меня есть data.frame, полный данных округа, я могу заменить значения NA на значения состояния, хранящиеся в другом data.frame. После написания того же merge
... ifelse (is.na ())
yada yada несколько десятков раз я решил сломать и написать функцию для этого.
Вот что я приготовил, а также пример того, как я это использую:
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") )
Итак, после того, как я запустил это, у меня возникло странное ощущение, что кто-то, вероятно, решил эту проблему раньше меня, и гораздо более элегантным способом.Есть ли лучшее / более простое / быстрое решение этой проблемы? Кроме того, есть ли способ устранить цикл в середине моей функции? Этот цикл существует, потому что я часто заменяю НА более чем в одном столбце. И, да, функция предполагает, что столбцы, которые мы заполняем из , названы одинаково, а столбцы, которые мы заполняем, от до , и то же самое применимо к слиянию.
Любое руководство или рефакторинг были бы полезны.
РЕДАКТИРОВАТЬ 2 декабря. Я понял, что в моем примере есть логические ошибки, которые я исправил.