Заполнение значений на панели данных
У меня есть данные панели, содержащие значения NA. Я хотел бы заполнить NAs значениями других данных. Допустим, я хочу завершить следующее panel
с помощью new.df
.
panel <- data.frame("time" = c(rep(2000,5), rep(2001,5)),
"var1" = rep(1:5, times=2),
"var2" = c(NA,'b','c',NA,'d','a1','b1','c1',NA,'d1'))
new.df <- data.frame("time" = c(2000:2001),
"var1" = c(4,4),
"var2" = c('e','e'))
Я попробовал другую комбинацию merge / aggregate / ddplyr и т. д.. Проблема в том, что merge
или merge.data.frame
создает дополнительные столбцы, индексируемые .x
и .y
, даже если имена столбцов идентичны.
> merge(panel,new.df,by = c("time","var1"), all=T)
time var1 var2.x var2.y
1 2000 1 <NA> <NA>
2 2000 2 b <NA>
3 2000 3 c <NA>
4 2000 4 <NA> e
5 2000 5 d <NA>
6 2001 1 a1 <NA>
7 2001 2 b1 <NA>
8 2001 3 c1 <NA>
9 2001 4 <NA> e
10 2001 5 d1 <NA>
Я также пытался играть с опцией na.action
без успеха, потому что панель все равно будет неполные после слияния и оставшиеся NA
должны оставаться такими, как они есть. (В зависимости от формулировки, обработка NA в некоторых случаях заменит NA
на 0
, или на NaN
)
new.df$var2
в нужное место, зная, что у меня есть очень большая панель, и она останется неполной в конце.
Заранее благодарю.
3 ответа:
Мы можем использовать
coalesce
изtidyr
library(tidyr) library(dplyr) full_join(as.data.frame(panel),as.data.frame(new.df),by = c("time","var1")) %>% mutate_each(funs(as.character), var2.x:var2.y) %>% mutate(var2= coalesce(var2.x, var2.y)) %>% select(-var2.x, -var2.y) # time var1 var2 #1 2000 1 <NA> #2 2000 2 b #3 2000 3 c #4 2000 4 e #5 2000 5 d #6 2001 1 a1 #7 2001 2 b1 #8 2001 3 c1 #9 2001 4 e #10 2001 5 d1
Или мы можем использовать опцию
base R
сmax.col
. Здесь ' d1 ' - это выход ОП сmerge
d1$var2 <-d1[,3:4][cbind(1:nrow(d1), max.col(!is.na(d1[3:4]), "first"))] d1$var #[1] NA "b" "c" "e" "d" "a1" "b1" "c1" "e" "d1"
Или просто (предполагая, что все значения в новом.ДФ карте на соответствующее значение на панели):
ind <- which(paste0(panel[,1],panel[,2]) %in% paste0(new.df[,1],new.df[,2])) panel[ind,3] = new.df[,3]
Воссоздать данные в виде фрейма данных
library(dplyr) panel <- data_frame("time" = c(rep(2000,5), rep(2001,5)), "var1" = rep(1:5, times=2), "var2" = c(NA,'b','c',NA,'d','a1','b1','c1',NA,'d1')) new.df <- data_frame("time" = c(2000:2001), "var1" = c(4,4), "var2" = c('e','e'))
Решение 1 Заполните значения NA основанием R merge
panelnew <- merge(panel,new.df,by = c("time","var1"), all=T) panelnew$var2 <- ifelse(is.na(panelnew$var2.x), panelnew$var2.y, panelnew$var2.x) panelnew[c("time","var1","var2")] time var1 var2 1 2000 1 <NA> 2 2000 2 b 3 2000 3 c 4 2000 4 e 5 2000 5 d 6 2001 1 a1 7 2001 2 b1 8 2001 3 c1 9 2001 4 e 10 2001 5 d1
Решение 2 Заполните значения NA dplyr left_join и мутируйте
Здесь я использую dplyr
left_join
, чтобы присоединить новые значения. Используйтеfull_join
, Если вы хотите также добавить комбинации time и var1, которых не было в исходной панели. Вы получите столбцыvar2.x
иvar2.y
, и это нормально, потому что это отражает тот факт, что есть старое и новое значение. Затем мутировать, чтобы заменить NA значения по новому значению.result <- panel %>% left_join(new.df, by = c("time", "var1")) %>% mutate(var2 = ifelse(is.na(var2.x),var2.y,var2.x))
Тогда, если вы хотите сохранить только интересующие столбцы
result <- result %>% select(time, var1, var2)
Что вы планируете делать, если новое значение заменяет существующее значение? Приведенный выше код сохранит старое значение.