Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add array1 (2D) to array2 (3D)?

I have 2 arrays that share 2 dimensions, but one has an additional dimension:

allpets <- array(data     = 1:9, dim= c(3, 3))
dimnames(allpets)[[2]]<-c("age","height","weight")

species<-array(data = 27:54, dim = c(3, 3,3))
dimnames(species)[[2]]<-c("age","height","weight")
dimnames(species)[[3]]<-c("dog", "cat", "fish")

allpets
     age height weight
[1,]   1      4      7
[2,]   2      5      8
[3,]   3      6      9


species
, , dog

     age height weight
[1,]  27     30     33
[2,]  28     31     34
[3,]  29     32     35

, , cat

     age height weight
[1,]  36     39     42
[2,]  37     40     43
[3,]  38     41     44

, , fish

     age height weight
[1,]  45     48     51
[2,]  46     49     52
[3,]  47     50     53

I would like to add the first array, allpets, to the matching column for each species of the array called species, so the result is:

, , dog

     age height weight
[1,]  28     34     40
[2,]  30     36     42
[3,]  32     38     44

, , cat

     age height weight
[1,]  37     43     49
[2,]  39     45     51
[3,]  41     47     53

, , fish

     age height weight
[1,]  46     52     58
[2,]  48     54     60
[3,]  50     56     62

I tried using apply, but can't seem to index the right parts to make this work?

sumpet <- function(x) {
  x + allpets
}

apply(species,c(2,3),sumpet)

I have a feeling this is relatively simple, but I am not using the right words to search for the solution. Conceptually, allpets is the baseline of some response and I am trying to add this baseline to each species-level response.

Thanks in advance!

like image 241
BirdNerd Avatar asked Jun 08 '26 17:06

BirdNerd


2 Answers

You could use sweep():

sweep(species, 1:2, allpets, FUN = "+")
#> , , dog
#> 
#>      age height weight
#> [1,]  28     34     40
#> [2,]  30     36     42
#> [3,]  32     38     44
#> 
#> , , cat
#> 
#>      age height weight
#> [1,]  37     43     49
#> [2,]  39     45     51
#> [3,]  41     47     53
#> 
#> , , fish
#> 
#>      age height weight
#> [1,]  46     52     58
#> [2,]  48     54     60
#> [3,]  50     56     62

Another approach using apply. There is a little bit more accounting because apply(...) converts to a matrix.

array(apply(species, 3L, "+", allpets), dim(species), dimnames(species))
like image 101
Cole Avatar answered Jun 11 '26 08:06

Cole


You could embed an lapply in a simplify2array.

simplify2array(setNames(lapply(seq(dim(species)[3]), function(x) species[,,x] + allpets),
                        dimnames(species)[[3]]))
# , , dog
# 
#      age height weight
# [1,]  28     34     40
# [2,]  30     36     42
# [3,]  32     38     44
# 
# , , cat
# 
#      age height weight
# [1,]  37     43     49
# [2,]  39     45     51
# [3,]  41     47     53
# 
# , , fish
# 
#      age height weight
# [1,]  46     52     58
# [2,]  48     54     60
# [3,]  50     56     62
like image 31
jay.sf Avatar answered Jun 11 '26 07:06

jay.sf