首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从一个返回多个值的函数赋值?

如何从一个返回多个值的函数赋值?
EN

Stack Overflow用户
提问于 2009-12-01 22:27:24
回答 12查看 279.9K关注 0票数 253

仍在尝试进入R逻辑...解包(在LHS上)返回多个值的函数的结果的“最佳”方法是什么?

显然我不能这么做:

代码语言:javascript
复制
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

我真的必须这样做吗?

代码语言:javascript
复制
R> r <- functionReturningTwoValues()
R> a <- r[1]; b <- r[2]

或者R程序员会写出更多类似这样的代码:

代码语言:javascript
复制
R> functionReturningTwoValues <- function() {return(list(first=1, second=2))}
R> r <- functionReturningTwoValues()
R> r$first
[1] 1
R> r$second
[1] 2

-编辑以回答沙恩的问题

我真的不需要给结果值部分命名。我将一个聚合函数应用于第一个组件,另一个聚合函数应用于第二个组件(minmax )。如果两个组件的函数相同,我就不需要拆分它们了)。

EN

回答 12

Stack Overflow用户

发布于 2009-12-02 07:21:20

我在互联网上偶然发现了这个聪明的黑客。我不确定它是讨厌的还是漂亮的,但它允许你创建一个“神奇的”运算符,允许你将多个返回值解压到它们自己的变量中。:=函数is defined here,并包含在下面,供后代使用:

代码语言:javascript
复制
':=' <- 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)) 
}

有了它,你就可以做你想做的事情了:

代码语言:javascript
复制
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

我不知道我对此有什么感觉。也许您会发现它在您的交互式工作空间中很有帮助。使用它来构建(重用)可用库(用于大众消费)可能不是最好的主意,但我猜这取决于您。

..。你知道他们怎么说责任和权力的..。

票数 71
EN

Stack Overflow用户

发布于 2009-12-01 23:01:58

通常我将输出包装成一个列表,这非常灵活(你可以在输出中使用数字,字符串,向量,矩阵,数组,列表,对象的任意组合)

就像这样:

代码语言:javascript
复制
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
票数 56
EN

Stack Overflow用户

发布于 2017-07-17 23:48:58

我组装了一个R包zeallot来解决这个问题。zeallot包括一个多重赋值或解包赋值运算符%<-%。运算符的LHS是要赋值的任意数量的变量,使用对c()的调用构建。运算符的RHS是一个矢量、列表、数据框、日期对象或任何具有实现的destructure方法的自定义对象(请参阅?zeallot::destructure)。

这里有几个基于原始帖子的例子。

代码语言:javascript
复制
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, ..)

有关更多信息和示例,请查看vignette包。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1826519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档