Как я могу добавить array1 (2D) в array2 (3D)?

#r #arrays #data-manipulation

#r #массивы #манипулирование данными

Вопрос:

У меня есть 2 массива, которые разделяют 2 измерения, но у одного есть дополнительное измерение:

 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
  

Я хотел бы добавить первый массив, allpets, в соответствующий столбец для каждого вида массива, называемого species, чтобы результат был:

 , , 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
  

Я пытался использовать apply, но, похоже, не могу проиндексировать нужные части, чтобы заставить это работать?

 sumpet <- function(x) {
  x   allpets
}

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

У меня такое чувство, что это относительно просто, но я не использую правильные слова для поиска решения. Концептуально allpets является базовой линией для некоторого ответа, и я пытаюсь добавить эту базовую линию к каждому ответу на уровне вида.

Заранее спасибо!

Комментарии:

1. Возможно, species array(allpets, dim = dim(species)) хотя это предполагает создание целого нового массива

2. Спасибо — это сработало! вы могли бы добавить это в качестве ответа

Ответ №1:

Вы могли бы использовать 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
  

Другой подход с использованием apply . Немного больше учета, потому что apply(...) преобразуется в матрицу.

 array(apply(species, 3L, " ", allpets), dim(species), dimnames(species))
  

Комментарии:

1. Это сработало, хотя и выдало предупреждение, которое не было проблемой для моего набора данных. Спасибо!

2. Из любопытства, какая версия R у вас есть? Я не видел предупреждения в sweep или apply в 4.0.2. Наконец, всегда полезно проверить решение, но вы можете смело дождаться дополнительных ответов или выбрать другой ответ

3. У меня R 3.4.4, и предупреждение было для версии sweep.

Ответ №2:

Вы могли бы встроить lapply в 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