14

是否可以从一个函数返回 4 个不同的数据帧?

设想:

我正在尝试读取文件、解析它并返回文件的某些部分。

我的函数看起来像这样:

parseFile <- function(file){

     carFile <- read.table(file, header=TRUE, sep="\t")

     carNames <- carFile[1,]
     carYear  <- colnames(carFile)

     return(list(carFile,carNames,carYear))
}

我不想使用 list(carFile,carNames,carYear)。有没有办法在不先将它们返回列表的情况下返回 3 个数据帧?

4

3 回答 3

24

R 不支持多个返回值。你想做这样的事情:

foo = function(x,y){return(x+y,x-y)}
plus,minus = foo(10,4)

是的?好吧,你不能。您会收到一个错误,即 R 无法返回多个值。

您已经找到了解决方案 - 将它们放在一个列表中,然后从列表中获取数据框。这是有效的——没有数据帧从一个内存块到另一个内存块的转换或复制。

这也是合乎逻辑的,函数的返回在概念上应该是一个具有某种含义的单个实体,该实体被转移到调用它的任何函数。如果您命名列表的返回值,也可以更好地传达此含义。

您可以使用一种技术在调用环境中创建多个对象,但是当您这样做时,小猫就会死去。

请注意,您的示例carYear中不是数据框 - 它是列名的字符向量。

于 2012-11-24T08:29:03.253 回答
3

如果你真的想要,在 R 中还有其他方法可以做到这一点。

assign('carFile',carFile,envir=parent.frame())

如果你使用它,那么 carFile 将在调用环境中创建。正如 Spacedman 所指出的,您只能从您的函数中返回一件事,而干净的解决方案是选择列表。

另外,我个人的看法是,如果你发现自己处于这种情况,你觉得你需要用一个函数返回多个数据帧,或者做一些以前没有人做过的事情,你真的应该重新审视你的方法。在大多数情况下,您可能会找到带有附加功能或推荐(即列表)的更清洁的解决方案。

换句话说

envir=parent.frame()

将完成这项工作,但正如 SpacedMan 提到的

当你这样做时,小猫会死

于 2014-01-07T17:05:42.493 回答
1

zeallot包以类似于 Python 可以从函数中解包变量的方式完成您所需要的工作。下面的可重现示例。

parseFile <- function(){

  carMPG <- mtcars$mpg
  carName <- rownames(mtcars)
  carCYL <- mtcars$cyl

  return(list(carMPG,carName,carCYL))
}

library(zeallot)
c(myFile, myName, myYear) %<-% parseFile()
于 2020-06-18T09:17:45.840 回答