以下简单示例将帮助我解决程序实现中的问题。
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],但它不起作用。
#知道如何做到这一点? 谢谢
答案 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实现可写的传递引用。它比超级对齐更安全,因为你知道变量在哪里被修改。