你可以使用
replace
来完成此操作,匹配两个向量的名称:
x + replace(rep(0, length(x)), names(x) %in% names(y), y)
假设x
和y
的名称顺序相同。
或者,您可以尝试以下方法,它不需要相同的顺序:
z <- x
m <- match(names(y), names(x))
z[m] <- z[m] + y
z
# A B C D
# 12 10 15 32
虽然这两种方法都不如 @RichardScriven 建议使用 tapply
来得简洁,但它们在处理大向量时更有效率:
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))
system.time(sum.josilber1(big.x, big.y))
system.time(sum.josilber2(big.x, big.y))
请注意,这两种提出的解决方案至少比本例中的
tapply
解决方案快 50 倍(
big.x
长度为 100 万,
big.y
长度为 50 万),因为它们执行单个向量化加法而不是许多较小的
sum
调用。