How can I take pairwise parallel maximum between two vectors?
Solution 1:
Pairwise maximum, pmax(a, b)
, will give c(3,4,6)
.
a <- c(3,3,5,NA,1)
b <- c(2,4,6,0,NA)
pmax(a, b)
# [1] 3 4 6 NA NA
pmax(a, b, na.rm = TRUE)
# [1] 3 4 6 0 1
There is also a pairwise minimum
pmin(a, b)
# [1] 2 3 5 NA NA
pmin(a, b, na.rm = TRUE)
# [1] 2 3 5 0 1
And a pairwise sum, which I pulled from this question/answer has been very useful to me at times:
psum(a, b) # == a + b
# [1] 5 7 11 NA NA
psum(a, b, na.rm = TRUE)
# [1] 5 7 11 0 1
psum(c(-1, NA, 4), c(0, NA, NA))
# [1] -1 NA NA
psum(c(-1, NA, 4), c(0, NA, NA), na.rm = TRUE)
# [1] -1 NA 4
psum <- function(..., na.rm = FALSE) {
dat <- do.call(cbind, list(...))
res <- rowSums(dat, na.rm = na.rm)
idx_na <- !rowSums(!is.na(dat))
res[idx_na] <- NA
res
}
Solution 2:
An alternative method which sacrifices b
:
# Where does b have smaller elements?
elsb <- which(a > b)
b[elsb] <- a[elsb]
b
# [1] 3 4 6
Solution 3:
Actually, the alternative solution deserves some credit. Use it for short vectors.
It is a lot faster when the vectors a and b are short. Changing the variable s in the code you can try it out yourself. When vectors have a length of 100 (s=20) pmax_new
is twice as fast. pmax
overtakes the alternative at a vector length of 2.500 (s=500).
require(microbenchmark)
pmax_new <- function(a, b) {
elsb <- which(a > b)
b[elsb] <- a[elsb]
b
}
a <- c(3,3,5,NA,1)
b <- c(2,4,6,0,NA)
s <- 20
microbenchmark( pmax(rep(a, s), rep(b, s)), times = 1E6 )
microbenchmark( pmax_new(rep(a, s), rep(b, s)), times = 1E6)