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

1 loops eval r object 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="")
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jos*_*ich 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"
> 
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我在我的生物中添加了"令人作呕和令人沮丧的代码的创造者". (9认同)
  • 我也会把它添加到我的生物中. (2认同)

Dan*_*ler 8

虽然它似乎有更好的方法来处理这个问题,如果你真的没有想用"的eval(解析(膏("方法,你错过的是文本标志.

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="")))
}
Run Code Online (Sandbox Code Playgroud)

除了不指定"文本="你错过了右侧几括号关闭您解析和eval语句.

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


mbq*_*mbq 5

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

name<-"x"
assign(name,3) #Eqiv to x<-3
Run Code Online (Sandbox Code Playgroud)

并通过以下方式删除:

name<-"x"
rm(list=name)
Run Code Online (Sandbox Code Playgroud)

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

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

  • Fortune(106):“如果答案是 parse(),你通常应该重新思考这个问题。” -- Thomas Lumley,R-help(2005 年 2 月) (3认同)

Gre*_*now 5

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

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

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