我希望在循环中分配对象。我已经读过某些形式的eval(parse(
是我需要执行的操作,但我遇到错误列出invalid text
或no 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 text
或no such file or directory
的错误。我在使用eval(parse(
时遗漏了什么?是否有更简单/更好的方法在循环中分配对象?
答案 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中使用eval
或parse
,除非你完全知道自己在做什么
可以使用以下方法创建变量:
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)