Why is using assign bad?

后端 未结 3 1688
悲&欢浪女
悲&欢浪女 2020-11-21 23:56

This post (Lazy evaluation in R – is assign affected?) covers some common ground but I am not sure it answers my question.

I stopped using assign when I

相关标签:
3条回答
  • 2020-11-22 00:01

    I'd like to point out that assign is meant to be used with environments.

    From that point of view, the "bad" thing in the example above is using a not quite appropriate data structure (the base environment instead of a list or data.frame, vector, ...).

    Side note: also for environments, the $ and $<- operators work, so in many cases the explicit assign and get isn't necessary there, neither.

    0 讨论(0)
  • 2020-11-22 00:03

    As the source of fortune(236) I thought I would add a couple examples (also see fortune(174)).

    First, a quiz. Consider the following code:

    x <- 1
    y <- some.function.that.uses.assign(rnorm(100))
    

    After running the above 2 lines of code, what is the value of x?

    The assign function is used to commit "Action at a distance" (see http://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming) or google for it). This is often the source of hard to find bugs.

    I think the biggest problem with assign is that it tends to lead people down paths of thinking that take them away from better options. A simple example is the 2 sets of code in the question. The lapply solution is more elegant and should be promoted, but the mere fact that people learn about the assign function leads people to the loop option. Then they decide that they need to do the same operation on each object created in the loop (which would be just another simple lapply or sapply if the elegant solution were used) and resort to an even more complicated loop involving both get and apply along with ugly calls to paste. Then those enamored with assign try to do something like:

    curname <- paste('myvector[', i, ']')
    assign(curname, i)
    

    And that does not do quite what they expected which leads to either complaining about R (which is as fair as complaining that my next door neighbor's house is too far away because I chose to walk the long way around the block) or even worse, delve into using eval and parse to get their constructed string to "work" (which then leads to fortune(106) and fortune(181)).

    0 讨论(0)
  • 2020-11-22 00:22

    Actually those two operations are quite different. The first gives you 26 different objects while the second gives you only one. The second object will be a lot easier to use in analyses. So I guess I would say you have already demonstrated the major downside of assign, namely the necessity of then needing always to use get for corralling or gathering up all the similarly named individual objects that are now "loose" in the global environment. Try imagining how you would serially do anything with those 26 separate objects. A simple lapply(foo, func) will suffice for the second strategy.

    That FAQ citation really only says that using assignment and then assigning names is easier, but did not imply it was "bad". I happen to read it as "less functional" since you are not actually returning a value that gets assigned. The effect looks to be a side-effect (and in this case the assign strategy results in 26 separate side-effects). The use of assign seems to be adopted by people that are coming from languages that have global variables as a way of avoiding picking up the "True R Way", i.e. functional programming with data-objects. They really should be learning to use lists rather than littering their workspace with individually-named items.

    There is another assignment paradigm that can be used:

     foo <- setNames(  paste0(letters,1:26),  LETTERS)
    

    That creates a named atomic vector rather than a named list, but the access to values in the vector is still done with names given to [.

    0 讨论(0)
提交回复
热议问题