Let A and B be arrays, of dimension [3,4,5] and [4,5], respectively.
E.g.,
A <- array(100,c(3, 4,5))
B <- array(80, c(4,5))
My desired answer is an array C of dimension [3,4,5] such that
C[i,j,k] = A[i,j,k] - B[j,k]
for all i,j,k
Edit Which answer is fastest code?
To evaluate the following three answers, I executed the following code to quantify the time of the three codes. The result is the following;
> mb
Unit: microseconds
expr min lq mean median uq max neval
f1 28.4 33.00 37.329 34.75 37.00 213.5 100
f2 32.5 37.65 40.069 38.95 40.55 103.0 100
f3 33.8 40.25 42.397 41.65 43.30 64.5 100
Thus the f1 is the most faster, thus I choose the answer of @user10488504 as an answer of this question.
Thank you, three persons @user10488504, @Stéphane Laurent and @Lyngbakr. I will use your suggesting code in my package. It helps me very much.
Code, which calculates running times.
f1 <- function(){
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
C <- array(aperm(sapply(1:dim(A)[1], function(i) A[i,,] - B)), dim(A))
}
f2<-function(){
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
sweep(A, c(2,3), B)
}
f3 <- function(){
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
# Perform calculation
res <- array(t(apply(A, MARGIN = 1, function(x)x-B)), c(3, 4, 5))
}
library(microbenchmark)
library(ggplot2)
mb <- microbenchmark(
f1 = f1(),
f2 = f2(),
f3 = f3()
)
mb
autoplot(mb)
With sweep:
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
> sweep(A, c(2,3), B)
, , 1
[,1] [,2] [,3] [,4]
[1,] 0 2 4 6
[2,] 1 3 5 7
[3,] 2 4 6 8
, , 2
[,1] [,2] [,3] [,4]
[1,] 8 10 12 14
[2,] 9 11 13 15
[3,] 10 12 14 16
, , 3
[,1] [,2] [,3] [,4]
[1,] 16 18 20 22
[2,] 17 19 21 23
[3,] 18 20 22 24
, , 4
[,1] [,2] [,3] [,4]
[1,] 24 26 28 30
[2,] 25 27 29 31
[3,] 26 28 30 32
, , 5
[,1] [,2] [,3] [,4]
[1,] 32 34 36 38
[2,] 33 35 37 39
[3,] 34 36 38 40
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With