문제

여전히 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

--- Shane의 질문에 답하기 위해 편집 ---

결과 값 부분에 이름을 부여 할 필요는 없습니다. 첫 번째 구성 요소에 하나의 집계 함수를 적용하고 다른 구성 요소에 두 번째 구성 요소에 적용하고 있습니다.min 그리고 max. 두 구성 요소 모두에 대해 동일한 기능이라면 분할 할 필요가 없습니다).

도움이 되었습니까?

해결책

(1) 목록 [...] <- 나는 10 년 전에 이것을 게시했다 R- 헬프. 그 이후로 GSUBFN 패키지에 추가되었습니다. 특수 연산자가 필요하지 않지만 왼쪽을 사용하여 작성해야합니다. list[...] 이와 같이:

library(gsubfn)  # need 0.7-0 or later
list[a, b] <- functionReturningTwoValues()

첫 번째 또는 두 번째 구성 요소 만 필요하면이 모든 작업도 다음과 같습니다.

list[a] <- functionReturningTwoValues()
list[a, ] <- functionReturningTwoValues()
list[, b] <- functionReturningTwoValues()

(물론 하나의 가치 만 필요하다면 functionReturningTwoValues()[[1]] 또는 functionReturningTwoValues()[[2]] 충분할 것입니다.)

더 많은 예제는 인용 된 r-help 스레드를 참조하십시오.

(2) 의도가 단순히 다중 값을 결합하고 반환 값을 명명 한 경우 간단한 대안은 사용하는 것입니다. with :

myfun <- function() list(a = 1, b = 2)

list[a, b] <- myfun()
a + b

# same
with(myfun(), a + b)

(3) 첨부 다른 대안은 다음과 같습니다.

attach(myfun())
a + b

추가 : with 그리고 attach

다른 팁

나는 인터넷 에서이 영리한 해킹을 우연히 발견했습니다 ... 나는 그것이 불쾌하거나 아름답는지 확실하지 않지만 여러 반환 값을 자신의 변수로 포장 할 수있는 "마법의"연산자를 만들 수 있습니다. 그만큼 := 기능 여기에 정의되어 있습니다, 후손을 위해 아래 포함 :

':=' <- function(lhs, rhs) {
  frame <- parent.frame()
  lhs <- as.list(substitute(lhs))
  if (length(lhs) > 1)
    lhs <- lhs[-1]
  if (length(lhs) == 1) {
    do.call(`=`, list(lhs[[1]], rhs), envir=frame)
    return(invisible(NULL)) 
  }
  if (is.function(rhs) || is(rhs, 'formula'))
    rhs <- list(rhs)
  if (length(lhs) > length(rhs))
    rhs <- c(rhs, rep(list(NULL), length(lhs) - length(rhs)))
  for (i in 1:length(lhs))
    do.call(`=`, list(lhs[[i]], rhs[[i]]), envir=frame)
  return(invisible(NULL)) 
}

그와 함께, 당신은 당신이 후에 할 수 있습니다.

functionReturningTwoValues <- function() {
  return(list(1, matrix(0, 2, 2)))
}
c(a, b) := functionReturningTwoValues()
a
#[1] 1
b
#     [,1] [,2]
# [1,]    0    0
# [2,]    0    0

나는 그것에 대해 어떻게 느끼는지 모르겠다. 아마도 대화식 작업 공간에서 도움이 될 수 있습니다. 이를 사용하여 사용 가능한 라이브러리를 구축하는 것이 (대량 소비를 위해) 가장 좋은 아이디어는 아닐 수도 있지만, 그것이 당신에게 달려 있다고 생각합니다.

... 당신은 그들이 책임과 힘에 대해 무엇을 말하는지 알고 있습니다 ...

일반적으로 출력을 매우 유연한 목록으로 랩핑합니다 (숫자, 문자열, 벡터, 매트릭스, 배열, 목록, 객체가 출력).

그처럼:

func2<-function(input) {
   a<-input+1
   b<-input+2
   output<-list(a,b)
   return(output)
}

output<-func2(5)

for (i in output) {
   print(i)
}

[1] 6
[1] 7
functionReturningTwoValues <- function() { 
  results <- list()
  results$first <- 1
  results$second <-2
  return(results) 
}
a <- functionReturningTwoValues()

나는 이것이 효과가 있다고 생각한다.

R 패키지를 모았습니다 ZealLot 이 문제를 해결합니다. ZealLot에는 여러 과제 또는 포장 풀기 할당 연산자가 포함되어 있습니다. %<-%. 연산자의 LHS는 호출을 사용하여 할당 할 수있는 여러 변수입니다. c(). 연산자의 RHS는 벡터, 목록, 데이터 프레임, 날짜 개체 또는 구현 된 사용자 정의 객체입니다. destructure 방법 (참조 ?zeallot::destructure).

다음은 원래 게시물을 기반으로 한 소수의 예입니다.

library(zeallot)

functionReturningTwoValues <- function() { 
  return(c(1, 2)) 
}

c(a, b) %<-% functionReturningTwoValues()
a  # 1
b  # 2

functionReturningListOfValues <- function() {
  return(list(1, 2, 3))
}

c(d, e, f) %<-% functionReturningListOfValues()
d  # 1
e  # 2
f  # 3

functionReturningNestedList <- function() {
  return(list(1, list(2, 3)))
}

c(f, c(g, h)) %<-% functionReturningNestedList()
f  # 1
g  # 2
h  # 3

functionReturningTooManyValues <- function() {
  return(as.list(1:20))
}

c(i, j, ...rest) %<-% functionReturningTooManyValues()
i     # 1
j     # 2
rest  # list(3, 4, 5, ..)

패키지를 확인하십시오 삽화 자세한 정보 및 예를 보려면.

이 질문에 대한 정답은 없습니다. 나는 당신이 데이터로 무엇을하고 있는지에 달려 있습니다. 위의 간단한 예에서는 다음과 같이 강력히 제안합니다.

  1. 가능한 한 간단하게 유지하십시오.
  2. 가능하면 기능을 벡터화하는 것이 가장 좋습니다. 이는 장기적으로 가장 많은 유연성과 속도를 제공합니다.

위의 값 1과 2에 이름이 중요합니까? 다시 말해,이 예에서 1과 2가 R [1]과 R [2]가 아닌 A와 B로 지명되는 것이 왜 중요한가? 이 맥락에서 이해해야 할 중요한 것은 A와 B가 또한 길이 1의 두 벡터 두 벡터를 참조 할 첨자가 필요없는 2 개의 새로운 벡터를 갖는 것 외에는 할당하는 과정에서 아무것도 바꾸지 않습니다.

> r <- c(1,2)
> a <- r[1]
> b <- r[2]
> class(r)
[1] "numeric"
> class(a)
[1] "numeric"
> a
[1] 1
> a[1]
[1] 1

인덱스보다 문자를 참조하려면 원래 벡터에 이름을 할당 할 수도 있습니다.

> names(r) <- c("a","b")
> names(r)
[1] "a" "b"
> r["a"]
a 
1 

편집하다 각 벡터에 최소 및 최대를 개별적으로 적용한다는 점을 감안할 때 매트릭스 (A와 B가 길이가 동일하고 데이터 유형이 동일한 경우) 또는 데이터 프레임 (A와 B가 길이가 같은 경우 A와 B가 동일한 경우)을 사용하는 것이 좋습니다. 그러나 다른 데이터 유형 일 수 있음) 또는 마지막 예제에서와 같이 목록을 사용합니다 (길이와 데이터 유형이 다를 수있는 경우).

> r <- data.frame(a=1:4, b=5:8)
> r
  a b
1 1 5
2 2 6
3 3 7
4 4 8
> min(r$a)
[1] 1
> max(r$b)
[1] 8

목록은이 목적에 완벽 해 보입니다. 예를 들어, 당신이 가진 기능 내에서

x = desired_return_value_1 # (vector, matrix, etc)

y = desired_return_value_2 # (vector, matrix, etc)

returnlist = list(x,y...)

}  # end of function

주요 프로그램

x = returnlist[[1]]

y = returnlist[[2]]

두 번째와 세 번째 질문에 예 - 과제 왼쪽에 여러 'lvalues'를 가질 수 없으므로해야 할 일입니다.

할당을 사용하는 것은 어떻습니까?

functionReturningTwoValues <- function(a, b) {
  assign(a, 1, pos=1)
  assign(b, 2, pos=1)
}

참조로 전달하려는 변수의 이름을 전달할 수 있습니다.

> functionReturningTwoValues('a', 'b')
> a
[1] 1
> b
[1] 2

기존 값에 액세스 해야하는 경우 assign ~이다 get.

A] FOO와 바 각각이 단일 숫자라면 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는 문자열의 벡터입니다).

C] 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-a-function-td858528.html

기능의 출력을 글로벌 환경으로 반환하려면 사용할 수 있습니다. list2env, 이 예에서와 같이 :

myfun <- function(x) { a <- 1:x
                       b <- 5:x
                       df <- data.frame(a=a, b=b)

                       newList <- list("my_obj1" = a, "my_obj2" = b, "myDF"=df)
                       list2env(newList ,.GlobalEnv)
                       }
    myfun(3)

이 기능은 글로벌 환경에서 세 가지 객체를 만듭니다.

> my_obj1
  [1] 1 2 3

> my_obj2
  [1] 5 4 3

> myDF
    a b
  1 1 5
  2 2 4
  3 3 3

함수에서 여러 출력을 얻고 원하는 형식으로 유지하려면 기능 내에서 작업 디렉토리에서 하드 디스크 (작업 디렉토리)에 출력을 저장 한 다음 기능 외부에서로드 할 수 있습니다.

myfun <- function(x) {
                      df1 <- ...
                      df2 <- ...
                      save(df1, file = "myfile1")
                      save(df2, file = "myfile2")
}
load("myfile1")
load("myfile2")
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top