How to add unequal length named vectors in R -


this must easy can't seem make work. have 2 named vectors of unequal length:

x <- as.vector(c(5, 10,15,20)) names(x) <- c("a", "b", "c", "d") y <- as.vector(c(7, 12)) names(y) <- c("a", "d") 

i want add them , preserve naming convention of longest. x + y yield:

a   b   c   d 12  10  15  32 

i've tried making lengths equal suggested elsewhere , allows arithmetic doesn’t preserve naming convention. i've tried things like:

z <- x[names(y)] + y 

but gets me arithmetic doesn't preserve structure.

you use replace this, matching names of 2 vectors:

x + replace(rep(0, length(x)), names(x) %in% names(y), y) #   b  c  d  # 12 10 15 32  

this assumes names of x , y in same order.

alternately, like, doesn't require same ordering:

z <- x m <- match(names(y), names(x)) z[m] <- z[m] + y z #   b  c  d  # 12 10 15 32  

though neither of these quite concise @richardscriven's suggestion of using tapply, both deal more efficient on large vectors:

set.seed(144) big.x <- runif(1000000) names(big.x) <- paste("x", 1:1000000) big.y <- big.x[sort(sample(1:1000000, 500000))] sum.rscriven <- function(x, y) {   z <- c(x, y)   tapply(z, names(z), sum) } sum.josilber1 <- function(x, y) x + replace(rep(0, length(x)), names(x) %in% names(y), y) sum.josilber2 <- function(x, y) {   z <- x   m <- match(names(y), names(x))   z[m] <- z[m] + y   z } system.time(sum.rscriven(big.x, big.y)) #    user  system elapsed  #  12.650   0.151  12.817  system.time(sum.josilber1(big.x, big.y)) #    user  system elapsed  #   0.214   0.002   0.215  system.time(sum.josilber2(big.x, big.y)) #    user  system elapsed  #   0.180   0.003   0.182  

note both proposed solutions @ least 50x faster tapply solution in example (big.x of length 1 million, big.y of length 500k), since perform single vectorized addition instead of many smaller calls sum.


Comments