assign () только для одного листа массива - избегайте ручного изменения - PullRequest
0 голосов
/ 06 августа 2020

У меня есть несколько массивов, которые мне нужно будет заполнить. Имена массивов переменные, но с ними будут выполняться одни и те же функции. В основном мне нужен способ заменить только один «лист» массива другим без ручного ввода имени массива. Пример ниже:

big_array_1 <- array(dim = c(5,5,10))
big_array_1[,,1] <- sample(c(1:10), 25, replace=T)

big_array_2 <- array(dim = c(5,5,10))
big_array_2[,,1] <- sample(c(40:50), 25, replace=T)


small_array <- array(dim = c(5,5,2))
small_array[,,] <- sample(c(20:30), 50, replace=T)

, поэтому каждый большой массив должен будет иметь второй лист (третье измерение), замененный вторым листом малого массива, но я хочу просто иметь возможность установить число ( т.е. большой массив «1» или «2»), чтобы эта работа работала в моем коде вместо того, чтобы каждый раз менять имя вручную.

# So I know I can do this, but I want to avoid manually changing the "_1" to "_2" when I run the script
big_array_1[,,2] <- small_array[,,2]

# instead, I'm hoping I can use a variable and some kind of assign()
arraynumber <- 1


# but this gives an error for assigning a non-language object
get(paste0("big_array_",arraynumber))[,,2] <- small_array[,,2]

# and this gives an error for invalid first argument. 
assign(get(paste0("big_array_",arraynumber))[,,2],  small_array[,,2])

# even though get(paste0("big_array_",arraynumber))[,,2] works on its own. 

Есть предложения?

1 Ответ

0 голосов
/ 06 августа 2020

В R нельзя присвоить значения результату get(). Кроме того, не рекомендуется использовать assign, даже attach, eval + parse, list2env и другие изменяющие среду, динамические c методы, которые, как правило, сложно отлаживать.

Как уже отмечалось, просто используйте именованные списки для идентично структурированных объектов. Списки могут содержать любой объект от массивов до фреймов данных и графиков без ограничения числа. Более того, вы избегаете переполнения глобальной среды отдельно именованными объектами, но работаете с несколькими списками, содержащими многие базовые элементы, которые лучше управляют данными для назначения или итерационных нужд.

Определение

set.seed(8620)

# NAMED LIST OF TWO ARRAYS 
big_array_list <- list(big_array_1 = array(dim = c(5,5,10)),
                       big_array_2 = array(dim = c(5,5,10)))

big_array_list$big_array_1[,,1] <- sample(c(1:10), 25, replace=TRUE)
big_array_list$big_array_2[,,1] <- sample(c(40:50), 25, replace=TRUE)

# NAMED LIST OF ONE ARRAY
small_array_list <- list(small_array_1 = array(sample(c(20:30), 50, replace=TRUE),
                                               dim = c(5,5,2)))

Назначение

# ASSIGN BY FIXED NAME
big_array_list$big_array_1[,,2] <- small_array_list$small_array_1[,,2]
big_array_list$big_array_1[,,2]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   30   29   26   24   23
# [2,]   21   20   22   20   24
# [3,]   27   24   26   30   30
# [4,]   30   26   24   29   25
# [5,]   26   21   26   20   30

# ASSIGN BY DYNAMIC NAME
arraynumber <- 1
big_array_list[[paste0("big_array_",arraynumber)]][,,2] <- small_array_list[[paste0("small_array_",arraynumber)]][,,2]
big_array_list[[paste0("big_array_",arraynumber)]][,,2]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   30   29   26   24   23
# [2,]   21   20   22   20   24
# [3,]   27   24   26   30   30
# [4,]   30   26   24   29   25
# [5,]   26   21   26   20   30

# ASSIGN BY INDEX
big_array_list[[1]][,,2] <- small_array_list[[1]][,,2]
big_array_list[[1]][,,2]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   30   29   26   24   23
# [2,]   21   20   22   20   24
# [3,]   27   24   26   30   30
# [4,]   30   26   24   29   25
# [5,]   26   21   26   20   30

Итерационные потребности

# RETURN DIMENSIONS OF EACH big_array
lapply(big_array_list, dim)

# SHOW FIRST 5 ELEMENTS OF EACH big_array
sapply(big_array_list, `[`, 1:5)

# RETURN LIST WHERE ALL big_arrays ARE EQUAL TO small_array 
mapply(`<-`, big_array_list, small_array_list, SIMPLIFY=FALSE)
...