2014-10-10 39 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