2014-10-10 40 views
0

我试图合并两个相同长度的向量,其中的NA在矢量“A”与矢量“b”的数字对齐,反之亦然:合并基于R中索引的两个向量

a <- c(1, NA, 3, NA) 
b <- c(NA, 2, NA, 4) 

的输出应该是:

1, 2 ,3, 4 

感谢您的帮助!

编辑:我所用的溶液是

a[is.na(a)] <- b[is.na(a)] 
+0

你能展示你试过的东西,并解释什么不起作用吗? – EWit 2014-10-10 18:42:40

+0

'这在您发布的修改中确实没有必要。 – 2014-10-12 20:57:34

回答

3

对应于is.na(a)的的a值应与b对应的is.na(b)否定的值来替换。这里我定义了一个新的矢量d,以便不覆盖原始矢量ab

d <- a 
d[is.na(d)] <- b[!is.na(b)] 
d 
# [1] 1 2 3 4 

如果你知道NA值在第二位置开始,你也可以交替的分配。

d <- a 
d[c(FALSE, TRUE)] <- b[c(FALSE, TRUE)] 
d 
# [1] 1 2 3 4 
+0

即将发布此确切解决方案。 – shadowtalker 2014-10-10 18:38:47

+0

完美谢谢! – Dave 2014-10-10 18:44:41

0

这里有一些更多的解决方案,可能会有更多的“文字”共振。他们有相当的产出:

m <- mapply(c, na.omit(a), na.omit(b), SIMPLIFY= FALSE) ## or, 
m <- Map(c, na.omit(a), na.omit(b)) 

output <- unlist(m) ## or, 
output <- Reduce(c, m) 

这样做有什么跨na.omit(a)na.omit(b)它首先会连接配对,然后串接所有这些对在一起。

至于性能也越高,这里是一个快速基准:

library(microbenchmark) 

gc() 

a <- (1:1e4)[c(TRUE, NA)] 
b <- (1:1e4)[c(NA, TRUE)] 

microbenchmark(
    unlist(mapply(c, na.omit(a), na.omit(b), SIMPLIFY= FALSE)), 
    unlist(Map(c, na.omit(a), na.omit(b))), 
    Reduce(c, mapply(c, na.omit(a), na.omit(b), SIMPLIFY= FALSE)), 
    Reduce(c, Map(c, na.omit(a), na.omit(b))), 
    times = 100 
) 

# Unit: milliseconds 
# expr  min  lq 
# unlist(mapply(c, na.omit(a), na.omit(b), SIMPLIFY = FALSE)) 4.476689 5.103025 
# unlist(Map(c, na.omit(a), na.omit(b))) 4.475753 4.902474 
# Reduce(c, mapply(c, na.omit(a), na.omit(b), SIMPLIFY = FALSE)) 75.974627 82.953051 
# Reduce(c, Map(c, na.omit(a), na.omit(b))) 75.919419 82.626217 
# median  uq  max neval 
# 5.488113 5.723023 10.59291 100 
# 5.422528 5.784764 13.04502 100 
# 86.082578 89.652660 114.94584 100 
# 85.761412 89.550317 158.90629 100 

不出所料,Reduceunlist慢得多。 Map只比mapply略慢。然而Reduce是非常普遍适用的,而unlist只能处理这种特殊情况。

+0

此解决方案仅在每个向量中NA的数量相同时才起作用。 – Dave 2014-10-10 19:01:55

+0

非常真实,但我不确定这是更多的“整理”问题还是“填补NA”的问题。这绝对是针对前者而不是后者。 – shadowtalker 2014-10-10 19:03:46

+0

非常“填补新手”的问题。实际上,我期望的解决方案是从矢量a指定NA的索引并插入b的值。 – Dave 2014-10-10 19:13:38