在循环中分配和删除对象:eval(解析(粘贴(

时间:2010-09-14 16:40:52

标签: r loops object eval paste

我希望在循环中分配对象。我已经读过某些形式的eval(parse(是我需要执行的操作,但我遇到错误列出invalid textno such file or directory.下面是一般示例代码我是试图做:

x <- array(seq(1,18,by=1),dim=c(3,2,3))
for (i in 1:length(x[1,1,])) {
  eval(parse(paste(letters[i],"<-mean(x[,,",i,"])",sep="")
}

当我完成使用这些对象时,我想删除它们(实际对象非常大,以后会导致内存问题......)

for (i in 1:length(x[1,1,])) eval(parse(paste("rm(",letters[i],")",sep="")))

此脚本的eval(parse(paste(部分都会返回invalid textno such file or directory的错误。我在使用eval(parse(时遗漏了什么?是否有更简单/更好的方法在循环中分配对象?

4 个答案:

答案 0 :(得分:10)

这是一个非常令人作呕和令人沮丧的方式。使用assign分配和rm的list参数以删除对象。

> for (i in 1:length(x[1,1,])) {
+   assign(letters[i],mean(x[,,i]))
+ }
> ls()
[1] "a" "b" "c" "i" "x"
> a
[1] 3.5
> b
[1] 9.5
> c
[1] 15.5
> for (i in 1:length(x[1,1,])) {
+   rm(list=letters[i])
+ }
> ls()
[1] "i" "x"
> 

每当你觉得需要使用parse时,请记住财富(106):

  

如果答案是解析()你应该   通常会重新考虑这个问题    - Thomas Lumley,R-help(2005年2月)

答案 1 :(得分:8)

虽然似乎有更好的方法来处理这个问题,但如果你真的做了想要使用“eval(解析(粘贴(”方法),那么你缺少的是文本标记。< / p>

parse假定它的第一个参数是一个文件的路径,然后它将解析。在您的情况下,您不希望它读取要解析的文件,您希望直接传递一些文本进行解析。所以,你的代码被重写(在上面被称为令人作呕的形式)将是

letters=c('a','b','c')
x <- array(seq(1,18,by=1),dim=c(3,2,3))
for (i in 1:length(x[1,1,])) {
  eval(parse(text=paste(letters[i],"<-mean(x[,,",i,"])",sep="")))
}

除了没有指定“text =”之外,你在右侧缺少几个括号来关闭你的解析和eval语句。

听起来你的问题已经解决了,但是对于那些到达此页面的人来说,确实想要使用eval(解析(粘贴,我想澄清一下)。

答案 2 :(得分:5)

最好避免使用eval(粘贴(或在这种情况下赋值)。要么创建许多全局变量,以后会引起额外的麻烦。

最好的方法是使用现有的数据结构来存储您的对象,对于这些类型的案例,列表是最常用的。

然后你可以使用[ls] apply函数来处理不同的元素,通常比循环遍历全局变量要快得多。如果要保存创建的所有对象,则只有一个要保存/加载的列表。当删除它们时,你只需要删除1个单个对象,一切都消失了(没有循环)。您可以命名列表的元素,以便稍后通过名称或索引来引用它们。

答案 3 :(得分:4)

非常糟糕的主意;你不应该在R中使用evalparse,除非你完全知道自己在做什么 可以使用以下方法创建变量:

name<-"x"
assign(name,3) #Eqiv to x<-3

并删除:

name<-"x"
rm(list=name)

但在你的情况下,可以使用简单的命名向量来完成:

apply(x,3,mean)->v;names(v)<-letters[1:length(v)]
v
v["b"]
#Some operations on v
rm(v)