R Заполнить многомерный массив входными данными из чередующихся векторов. - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь заполнить многомерный массив двумя векторами одинаковой длины. Входные данные должны чередоваться между векторами, так что первый вход является первым объектом первого вектора, второй вход является первым объектом второго вектора и так далее. Я искал похожие проблемы на этом сайте и нашел функцию rbind (), однако она не будет работать, как только мое третье измерение не будет равно 1.

Короче говоря, я хочу добиться этого:

a <- 1:6
b <- c("a","b","c","d","e","f")

# output array
, , 1

     [,1] [,2]
[1,] "1"  "a" 
[2,] "2"  "b" 
[3,] "3"  "c" 

, , 2

     [,1] [,2]
[1,] "4"  "d" 
[2,] "5"  "e" 
[3,] "6"  "f" 

У меня есть рабочее решение ниже, использующее три цикла for, но это кажется слишком сложным.

a <- 1:6
b <- c("a","b","c","d","e","f")
len <- prod(length(a)+length(b))

myarray <- array(rep(F,len),dim=c(3,2,2))

counter <- 1
for (n in 1:dim(myarray)[3]) { # n 2
  for (r in 1:dim(myarray)[1]) { # rows 3
    for (c in 1:dim(myarray)[2]) { # columns 2
      if (c %% 2 != 0) {
        myarray[r,c,n] <- a[counter]
      } else {
        myarray[r,c,n] <- b[counter]
      }
    }
    counter <- counter + 1
  }
}

Есть ли более простой подход? (Я уверен, что я упускаю что-то очень простое здесь, но я новичок в R и сам не могу понять это)

Спасибо за чтение!

[ПРАВИТЬ] Код должен быть применим к набору данных с любой длиной вектора и любым измерением dim = c (x, y, z). Пример данных можно найти в базе данных Dryad https://doi.org/10.5061/dryad.mp713, «Таблица 1 Arcti c char наземные ориентиры», которая содержит 13 пар xy-координат от 121 индивидуума arcti c char fi sh (тусклый = c (13,2,121)).

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Вот мое решение проблемы с dim = c(13,2,121):

M <- cbind(a, b)
array(sapply(seq(1, length(a), 13), function(i) M[i:(i+12),]), c(13,2,121))

Не забудьте сохранить результат Mneu <- ...

Для вашего небольшого примера:

M <- cbind(a, b);
array(sapply(seq(1, length(a), 3), function(i) M[i:(i+2),]), c(3,2,2))
1 голос
/ 07 февраля 2020

Сформируйте массив и затем перестановите размеры:

aperm(array(cbind(a, b), c(3, 2, 2)), c(1, 3:2))

, давая:

, , 1

     [,1] [,2]
[1,] "1"  "a" 
[2,] "2"  "b" 
[3,] "3"  "c" 

, , 2

     [,1] [,2]
[1,] "4"  "d" 
[2,] "5"  "e" 
[3,] "6"  "f" 

Примечание

Мы можем немного обобщить пример:

n <- 6 # must be 26 or less so that we can use letters below
a <- 1:n
b <- head(letters, n)

aperm(array(cbind(a, b), c(n/2,2,2)), c(1, 3:2))
...