#r #arrays
#r #массивы
Вопрос:
У меня есть массив списка режимов, например, созданный из следующего кода tapply:
my.data <- data.frame(expand.grid(species = c(1:3), year = c(1972:2000), VA = c(1:10), SA=c(1:3)))
test <- tapply(my.data$SA, list(my.data$species,my.data$year, my.data$VA), as.character)
mode(test)
#> [1] "list"
is.array(test)
#> [1] TRUE
Как мне использовать abind для добавления дополнительного измерения? Использование abind выдаст мне ошибку из-за режима «список»
test2 <- abind(test, test[,,1])
#> Error in abind(test, test[, , 1]) :
#> can only supply one list-valued argument for ...
Заранее благодарю вас.
Ответ №1:
Вам нужно передать список в abind
, поэтому просто поместите test
и test[,,1]
в список и передайте это:
dim(test)
#> [1] 3 29 10
library(abind)
test2 <- abind(list(test, test[,,1]))
dim(test2)
#> [1] 3 29 11
Однако это может быть не тот результат, который вы ищете, поскольку в вашем исходном трехмерном массиве каждая «ячейка» фактически представляет собой список, содержащий вектор символов длиной 3. Возможно, нет никакого способа обойти это, если символьные векторы в ваших реальных данных имеют разную длину, но если все они имеют одинаковую длину, то лучше всего было бы построить 4-мерный массив, подобный этому:
test <- array(unlist(test), dim = c(dim(test), length(test[[1]])))
dimnames(test) <- list(element = 1:3, year = 1972:2000, VA = 1:10, species = 1:3)
dim(test)
#> [1] 3 29 10 3
Теперь также будет намного проще отслеживать, с каким измерением вы работаете.
Например:
test[,,VA = 3,]
#> , , species = 1
#>
#> year
#> element 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> year
#> element 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> year
#> element 1996 1997 1998 1999 2000
#> 1 "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3"
#>
#> , , species = 2
#>
#> year
#> element 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> year
#> element 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> year
#>
#> ...etc
Если вы хотите добавить дополнительный элемент в измерение «элемент», вы могли бы сделать
test2 <- abind(list(test, test[1,,,]), along = 1)
test2
#> , , 1
#>
#> 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997
#> 1 "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 2 "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2" "2"
#> 3 "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3" "3"
#> "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1" "1"
#> 1998 1999 2000
#> 1 "1" "1" "1"
#> 2 "2" "2" "2"
#> 3 "3" "3" "3"
#> "1" "1" "1"
#>
#> ... etc
Комментарии:
1. Спасибо, Аллан, в реальном наборе данных фактически каждая ячейка имеет разную длину символьного вектора, и дополнительное измерение, которое мне нужно добавить, — это слияние двух исходных измерений (например, каждая ячейка test[,,3] = c(test[,,1], test[,,2]). Так что я все еще не могу найти решение…
2. @Miguel если вы просто хотите объединить векторы в каждой ячейке
test[,,1]
иtest[,,2]
в срезtest[,,3]
, вы можете сделатьtest[,,3] <- mapply(c, test[,,1], test[,,2], SIMPLIFY = FALSE)