我有一个包含NA值的面板数据。我想用其他数据的值来填写NA。假设我想用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
,因为我知道我有一个非常大的面板,并且最后它将保持不完整。 / p>
提前致谢。
答案 0 :(得分:2)
我们可以使用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'是OP的输出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"
答案 1 :(得分:1)
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'))
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
这里我使用dplyr left_join
加入新值。如果您还想添加原始面板中不存在的时间和var1的组合,请使用full_join
。您将获得列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)
如果新值替换现有值,您打算做什么? 上面的代码将保留旧值。
答案 2 :(得分:1)
或者简单地说(假设new.df中的所有值都映射到Panel中相应的NA值):
ind <- which(paste0(panel[,1],panel[,2]) %in% paste0(new.df[,1],new.df[,2]))
panel[ind,3] = new.df[,3]