仍在尝试进入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
)。如果两个组件的函数相同,我就不需要拆分它们了)。
发布于 2009-12-02 07:21:20
我在互联网上偶然发现了这个聪明的黑客。我不确定它是讨厌的还是漂亮的,但它允许你创建一个“神奇的”运算符,允许你将多个返回值解压到它们自己的变量中。:=
函数is defined here,并包含在下面,供后代使用:
':=' <- 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
我不知道我对此有什么感觉。也许您会发现它在您的交互式工作空间中很有帮助。使用它来构建(重用)可用库(用于大众消费)可能不是最好的主意,但我猜这取决于您。
..。你知道他们怎么说责任和权力的..。
发布于 2009-12-01 23:01:58
通常我将输出包装成一个列表,这非常灵活(你可以在输出中使用数字,字符串,向量,矩阵,数组,列表,对象的任意组合)
就像这样:
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
发布于 2017-07-17 23:48:58
我组装了一个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, ..)
有关更多信息和示例,请查看vignette包。
https://stackoverflow.com/questions/1826519
复制相似问题