Как назначить из функции, которая возвращает более одного значения? - PullRequest
198 голосов
/ 01 декабря 2009

Все еще пытаясь разобраться в логике R ... каков "лучший" способ распаковать (на LHS) результаты функции, возвращающей несколько значений?

Я не могу этого сделать, по-видимому:

R> functionReturningTwoValues <- function() { return(c(1, 2)) }
R> functionReturningTwoValues()
[1] 1 2
R> a, b <- functionReturningTwoValues()
Error: unexpected ',' in "a,"
R> c(a, b) <- functionReturningTwoValues()
Error in c(a, b) <- functionReturningTwoValues() : object 'a' not found

Должен ли я действительно делать следующее?

R> r <- functionReturningTwoValues()
R> a <- r[1]; b <- r[2]

или программист на R напишет что-то вроде этого:

R> functionReturningTwoValues <- function() {return(list(first=1, second=2))}
R> r <- functionReturningTwoValues()
R> r$first
[1] 1
R> r$second
[1] 2

--- отредактировано, чтобы отвечать на вопросы Шейна ---

Мне не нужно давать имена частям значения результата. Я применяю одну агрегатную функцию к первому компоненту, а другую - ко второму компоненту (min и max. Если бы это была одна и та же функция для обоих компонентов, мне не нужно было бы их разбивать).

Ответы [ 12 ]

1 голос
/ 14 августа 2016

[A] Если каждый из foo и bar является одним числом, то с c нет ничего плохого (foo, bar); и вы также можете назвать компоненты: c (Foo = foo, Bar = bar). Таким образом, вы можете получить доступ к компонентам результата 'res' как res [1], res [2]; или, в именованном случае, как res ["Foo"], res ["BAR"].

[B] Если foo и bar являются векторами одного типа и длины, то, опять же, нет ничего плохого в возврате cbind (foo, bar) или rbind (foo, bar); также можно назвать В случае 'cbind' вы можете получить доступ к foo и bar как res [, 1], res [, 2] или как res [, "Foo"], res [, "Bar"]. Вы также можете предпочесть вернуть фрейм данных, а не матрицу:

data.frame(Foo=foo,Bar=bar)

и получите к ним доступ как res $ Foo, res $ Bar. Это также будет хорошо работать, если foo и bar имеют одинаковую длину, но не одного типа (например, foo - это вектор чисел, а bar - вектор символьных строк).

[С] Если foo и bar достаточно разные, чтобы их не было удобно комбинировать, как указано выше, тогда вы обязательно должны вернуть список.

Например, ваша функция может соответствовать линейной модели и также рассчитать прогнозные значения, чтобы вы могли иметь

LM<-lm(....) ; foo<-summary(LM); bar<-LM$fit

и затем вы бы return list(Foo=foo,Bar=bar) и затем получили доступ к сводке как res $ Foo, прогнозируемые значения как res $ Bar

источник: http://r.789695.n4.nabble.com/How-to-return-multiple-values-in-a-function-td858528.html

0 голосов
/ 17 мая 2017

Чтобы получить несколько выходов из функции и сохранить их в нужном формате, вы можете сохранить выходы на жесткий диск (в рабочем каталоге) из функции, а затем загрузить их извне функции:

myfun <- function(x) {
                      df1 <- ...
                      df2 <- ...
                      save(df1, file = "myfile1")
                      save(df2, file = "myfile2")
}
load("myfile1")
load("myfile2")
...