Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtract array with different size in R

Tags:

arrays

r

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. enter image description here 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)
like image 499
Camford Oxbridge Avatar asked Jun 18 '26 19:06

Camford Oxbridge


1 Answers

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
like image 140
Stéphane Laurent Avatar answered Jun 20 '26 08:06

Stéphane Laurent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!