Преобразование списка в аргумент «два или более объектов» в R

#r #arguments

#r #аргументы

Вопрос:

Я должен вызвать функцию в R, которая принимает «2 или более объектов» в качестве входных данных, поэтому определение функции является:

function(..., all = TRUE, <other named parameters>)

где … определяется как 2 or more objects

Проблема в том, что мои объекты находятся в списке, и я работаю с разным количеством объектов в зависимости от того, что я хочу сделать. Итак, если мой список содержит, например, 3 элемента, мне пришлось бы сделать:

function(list[[1]], list [[2]], list[[3]])

Как я могу сделать это в общем случае, независимо от количества элементов в моем списке?

Ответ №1:

Вы можете использовать do.call, поскольку он принимает список аргументов и применяет их к функции. Например, для rbind :

 X <- list(A=1:3,B=4:6,C=7:9)
do.call(rbind,X)

  [,1] [,2] [,3]
A    1    2    3
B    4    5    6
C    7    8    9
  

Имейте в виду, если вам нужны дополнительные аргументы, вы также должны добавить их в список. Смотрите, например :

 X <- list(A=list(A1=1:2,A2=3:4),B=list(B1=5:6,B2=7:8))

do.call(c,X)      # Returns a list
do.call(c,X,recursive=TRUE)  # Gives an error
do.call(c,c(X,list(recursive=TRUE)))

A.A11 A.A12 A.A21 A.A22 B.B11 B.B12 B.B21 B.B22 
    1     2     3     4     5     6     7     8 
  

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

1. Вы можете передать рекурсивный аргумент за один раз. do.call("c", list(X,recursive=TRUE)) . Цитирование функции (здесь c ) зависит от предпочтений.

2. В некоторых случаях да, но если X это список списков, это не совсем сработает. Он будет работать с дополнительным параметром, foo с c(X, foo=TRUE) которым foo является скалярное значение. Однако в этом случае дополнительный параметр recursive является параметром для c функции, поэтому способ Йориса, возможно, является единственным способом. Если дополнительным параметром является вектор, c(X, foo=list(11:15)) сработает.

3. @Aaron : Я не понимаю, к чему ты клонишь. X — это список списков в моем примере, а c(list1,list2) создает список, содержащий элементы обоих списков, так что это кажется желательным поведением в данном случае. Можете ли вы привести пример того, где это не работает?

4. ab <- list(a=1:3,b=4:6); c <- list(c=5:7) Затем сравните do.call(cbind, list(ab, c)) и do.call(cbind, c(ab, c)) .

5. @Aaron : Я вижу, откуда берется путаница. recursive здесь является дополнительным аргументом функции c и должен быть объединен с исходным списком с помощью c() . В вашем примере вы либо вызываете cbind для списка списков, либо для списка, созданного путем объединения двух списков. Это не противоречит тому, что говорит Роман, наоборот. Главное здесь в том, что do.call имеет только два аргумента: функцию и список. И список передается в качестве аргументов функции.

Ответ №2:

Пример был бы полезен, но я почти уверен, что вы ищете do.call :

 do.call(function, c(list, list(all=TRUE, <other named parameters>)))