R:在函数中存储数据并在不使用"返回"的情况下进行检索。

时间:2014-08-13 03:59:41

标签: r

以下简单示例将帮助我解决程序实现中的问题。

fun2<-function(j)
{
x<-rnorm(10)
y<-runif(10)
Sum<-sum(x,y)
Prod<-prod(x,y)
return(Sum)
}
j=1:10
Try<-lapply(j,fun2)

我想存储&#34; Prod&#34;在每次迭代时,我都可以在运行fun2函数后访问它。我尝试使用assign()来创建空间分配(&#34; Prod&#34;,numeric(10),pos = 1) 然后在第j次迭代时将Prod分配给Prod [j],但它不起作用。

知道如何做到这一点? 谢谢

4 个答案:

答案 0 :(得分:2)

您可以在return()命令中添加任何您喜欢的内容。您可以返回列表return(list(Sum,Prod))或数据框return(data.frame("In"=j,"Sum"=Sum,"Prod"=Prod))

然后我会将data.frames列表转换为单个data.frame

Try2 <- do.call(rbind,Try)

答案 1 :(得分:1)

也许以更加矢量化的方式重新思考问题,利用隐含的对称性将中间值表示为矩阵并对其进行操作

ni = 10; nj = 20
x = matrix(rnorm(ni * nj), ni)
y = matrix(runif(ni * nj), ni)
sums = colSums(x + y)
prods = apply(x * y, 2, prod)

考虑矢量化版本适用于你的“真实”问题,与sum / prod示例一样;在实践中,当考虑向量失败时,我从未在其他答案中使用环境或连接方法,而是返回列表或向量的简单解决方案。

答案 2 :(得分:0)

我以前做过这件事,而且有效。很适合快速解决,但它有点马虎。 &lt;&lt; - 运算符将函数外部分配给全局环境。

fun2<-function(j){
  x<-rnorm(10)
  y<-runif(10)
  Sum<-sum(x,y)
  Prod[j]<<-prod(x,y)
}
j=1:10
Prod <- numeric(length(j))
Try<-lapply(j,fun2)
Prod

答案 3 :(得分:0)

thelatemail和JeremyS的解决方案可能就是你想要的。使用列表是传递一堆不同数据项的常用方法,我建议您使用它。引用这里没有人认为我提倡直接选择。

return(list(Sum,Prod))

话虽如此,假设您确实不想传回它们,您也可以使用assign或超级对齐运算符将它们直接放在函数内的父环境中。功能编程纯粹主义者可以忽略这种做法,但它确实有效。这基本上就是你原本想要做的事情。

这是超级对齐版本

fun2<-function(j)
{
  x<-rnorm(10)
  y<-runif(10)
  Sum<-sum(x,y)
  Prod[j] <<- prod(x,y)
  return(Sum)
}
j=1:10
Prod <- numeric(10)
Try<-lapply(j,fun2)

请注意,超级对象会搜索变量存在的第一个环境并在那里修改它。它不适合在你以上的地方创建新的变量。

直接使用环境的示例版本

fun2<-function(j,env)
{
  x<-rnorm(10)
  y<-runif(10)
  Sum<-sum(x,y)
  env$Prod[j] <- prod(x,y)
  return(Sum)
}
j=1:10
Prod <- numeric(10)
Try<-lapply(j,fun2,env=parent.frame())

请注意,如果您已从函数中调用parent.frame(),则需要返回两个帧,因为lapply()会创建自己的帧。这种方法的优势在于您可以将任何环境传递给它而不是parent.frame(),并且可以在那里修改值。这是很少使用的R实现可写的传递引用。它比超级对齐更安全,因为你知道变量在哪里被修改。