Создание функции для замены NA из одного data.frame значениями из другого

У меня регулярно возникают ситуации, когда мне нужно заменить отсутствующие значения из 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 декабря. Я понял, что в моем примере есть логические ошибки, которые я исправил.

17
задан Arun 30 March 2013 в 15:42
поделиться