Assigning and removing objects in a loop: eval(parse(paste(

后端 未结 4 1992
没有蜡笔的小新
没有蜡笔的小新 2020-12-16 09:07

I am looking to assign objects in a loop. I\'ve read that some form of eval(parse( is what I need to perform this, but I\'m running into errors listing in

相关标签:
4条回答
  • 2020-12-16 09:17

    Although it seems there are better ways to handle this, if you really did want to use the "eval(parse(paste(" approach, what you're missing is the text flag.

    parse assumes that its first argument is a path to a file which it will then parse. In your case, you don't want it to go reading a file to parse, you want to directly pass it some text to parse. So, your code, rewritten (in what has been called disgusting form above) would be

    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="")))
    }
    

    In addition to not specifying "text=" you're missing a few parentheses on the right side to close your parse and eval statements.

    It sounds like your problem has been solved, but for people who reach this page who really do want to use eval(parse(paste, I wanted to clarify.

    0 讨论(0)
  • 2020-12-16 09:22

    It is best to avoid using either eval(paste( or assign in this case. Doing either creates many global variables that just cause additional headaches later on.

    The best approach is to use existing data structures to store your objects, lists are the most general for these types of cases.

    Then you can use the [ls]apply functions to do things with the different elements, usually much quicker than looping through global variables. If you want to save all the objects created, you have just one list to save/load. When it comes time to delete them, you just delete 1 single object and everything is gone (no looping). You can name the elements of the list to refer to them by name later on, or by index.

    0 讨论(0)
  • 2020-12-16 09:28

    That's a pretty disgusting and frustrating way to go about it. Use assign to assign and rm's list argument to remove objects.

    > 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"
    > 
    

    Whenever you feel the need to use parse, remember fortune(106):

    If the answer is parse() you should usually rethink the question.
    -- Thomas Lumley, R-help (February 2005)

    0 讨论(0)
  • 2020-12-16 09:30

    Very bad idea; you should never use eval or parse in R, unless you perfectly know what you are doing.
    Variables can be created using:

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

    And removed by:

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

    But in your case, it can be done with simple named vector:

    apply(x,3,mean)->v;names(v)<-letters[1:length(v)]
    v
    v["b"]
    #Some operations on v
    rm(v)
    
    0 讨论(0)
提交回复
热议问题