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.