我期待在循环中分配对象.我已经读过某些形式的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="")
}
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月)
虽然它似乎有更好的方法来处理这个问题,如果你真的没有想用"的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(解析(粘贴,我想澄清一下).
非常糟糕的主意;你永远不应该在 R 中使用eval或parse,除非你完全知道你在做什么。
可以使用以下方法创建变量:
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)
最好避免使用eval(粘贴(或在这种情况下赋值).要么创建许多全局变量,以后会引起额外的麻烦.
最好的方法是使用现有的数据结构来存储对象,对于这些类型的情况,列表是最常用的.
然后你可以使用[ls] apply函数来处理不同的元素,通常比循环遍历全局变量要快得多.如果要保存创建的所有对象,则只有一个要保存/加载的列表.当删除它们时,你只需要删除1个单个对象,一切都消失了(没有循环).您可以命名列表的元素,以便稍后通过名称或索引来引用它们.