R: как связать множество массивов, используя имена, хранящиеся в символьном векторе

#r

#r

Вопрос:

У меня есть символьный вектор имен массивов в моей среде. например

 test.list lt;- (paste0("test.array",1:3))  

Я хочу использовать эти имена для привязки массивов, что-то вроде:

 test.array.bind1 lt;- abind(test.list[1:3], along = 5)  

но это приводит к ошибке:

 Error in abind(test.list[1:3], along = 5) : along must be between 0 and 2  

Я считаю, что он не обрабатывает входные данные как имена объектов, потому что он работает, когда я записываю имена вручную.

 test.array.bind lt;- abind(test.array1, test.array2, test.array3, along = 5)  

Я попробовал некоторые варианты, такие как:

 test.array.bind1 lt;- abind(paste(test.list[1:3], sep = ","), along = 5)  

но получаю ту же ошибку.

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

Я мог бы просто ввести имена несколько раз за тот час, который мне потребовался, чтобы попытаться найти решение до сих пор (в моих реальных данных гораздо больше, чем 3!), Но я продолжаю сталкиваться с подобными проблемами, поэтому я задался вопросом, существует ли автоматическое решение.

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

1. Возможно, вам нужно do.call(abind, c(mget(test.list[1:3]), along = 5))

2. Это не совсем сработало «Ошибка в mget(test.list[1:3], along = 5) : неиспользуемый аргумент (along = 5)», но, основываясь на этом, у этого, похоже, есть «тест. массив.привязка2

3. Я думаю, что вы используете предыдущую версию с опечаткой. Я забыл завернуть ) после mget того, как . Отредактированный комментарий должен сработать

4. Да, прямо сейчас. Эти два теперь дают один и тот же результат.

Ответ №1:

Нам нужно mget получить значение объектов в a list , а затем использовать abind в do.call

 library(abind) out1 lt;- do.call(abind, c(mget(test.list[1:3]), along = 5))  

ПРИМЕЧАНИЕ: [1:3] Не требуется, если в length «test.list» vector всего 3

-тестирование с помощью кода OP

 gt; out2 lt;- abind(test.array1, test.array2, test.array3, along = 5) gt; all.equal(out1, out2, check.attributes = FALSE) [1] TRUE  

данные

 test.array1 lt;- array(1:50, dims = c(2, 2, 2, 3, 2)) test.array2 lt;- array(51:100, dim = c(2, 2, 2, 3, 2)) test.array3 lt;- array(101:150, dim = c(2, 2, 2, 3, 2)) test.list lt;- paste0("test.array", 1:3)  

Ответ №2:

Вы тоже можете это сделать

 library(tidyverse)  df1 = tibble(  id = 1:10,  x = rnorm(10) )  df2 = tibble(  id = 1:10,  x = 2,  y = rnorm(10) )  df3 = tibble(  id = 1:10,  x = 3,  y = 2,  z = rnorm(10) )  env = environment()  df = tibble() %gt;%   bind_rows(env[["df1"]]) %gt;%   bind_rows(env[["df2"]]) %gt;%   bind_rows(env[["df3"]]) df  

выход

 # A tibble: 30 x 4  id x y z  lt;intgt; lt;dblgt; lt;dblgt; lt;dblgt;  1 1 -1.80 NA NA  2 2 0.143 NA NA  3 3 -0.620 NA NA  4 4 1.25 NA NA  5 5 -0.502 NA NA  6 6 -0.954 NA NA  7 7 0.533 NA NA  8 8 2.33 NA NA  9 9 0.207 NA NA 10 10 0.277 NA NA # ... with 20 more rows  

И вот так

 addDf = function(df, dfnames){  for(dfn in dfnames) df = df %gt;% bind_rows(env[[dfn]])  df }  df = tibble() %gt;% addDf(c("df1", "df2", "df3")) df  

выход

 # A tibble: 30 x 4  id x y z  lt;intgt; lt;dblgt; lt;dblgt; lt;dblgt;  1 1 -1.80 NA NA  2 2 0.143 NA NA  3 3 -0.620 NA NA  4 4 1.25 NA NA  5 5 -0.502 NA NA  6 6 -0.954 NA NA  7 7 0.533 NA NA  8 8 2.33 NA NA  9 9 0.207 NA NA 10 10 0.277 NA NA # ... with 20 more rows