this question has answer here:
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
Post a Comment