简体   繁体   中英

Merge two vectors based on index in R

I'm trying to merge two vectors of same length where NAs in vector "a" align with the numbers in vector "b" and vice versa:

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

The output should be:

1, 2 ,3, 4

Thanks for the help!

edit: the solution I used was

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

The values of a that correspond to is.na(a) should be replaced with the values of b that correspond to the negation of is.na(b) . Here I define a new vector d so as to not over-write the original vectors a or b .

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

If you know the NA values begin in the second position, you could also alternate the assignment.

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

Here are some more solutions that might have more "literal" resonance. They have equivalent outputs:

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) 

What this does it first concatenates pairs across na.omit(a) and na.omit(b) , and then concatenates all those pairs together.

As far as performance goes, here is a quick benchmark:

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

Unsurprisingly, Reduce is much slower than unlist . Map is only slightly slower than mapply . However Reduce is much, much more generally applicable, whereas unlist can really only handle this special case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM