1

I have a function in which I use the superassingment operator to update a variable in the global environment. This works fine as long as it is a single value e.g.

    a <<- 3

However I get errors with subsets of data frames and data tables e.g.

    a <- c(1,2,3)
    a[3] <<- 4
    Error in a[3] <<- 4 : object 'a' not found 

Any idea why this is and how to solve it?

Thanks!

rickwol
  • 35
  • 3
  • 3
    `library("fortunes"); fortune(174)` and http://www.burns-stat.com/pages/Tutor/R_inferno.pdf Circle 6 – jogo Dec 14 '18 at 13:03
  • This error is confusing though, anybody know where it comes from ? – moodymudskipper Dec 14 '18 at 16:05
  • @Moody_Mudskipper I think it depends from which point in the searchpath the search for the object begins. – jogo Dec 14 '18 at 16:13
  • but `<<-` works fine in current environment, and there is no such thing as `[<<-` so I'm not even sure what is executed, `debugonce("<<-");a[3] <<- 4` shows the function isn't even called. – moodymudskipper Dec 14 '18 at 16:18

1 Answers1

3

The superassignment operator and other scope-breaking techniques should be avoided if at all possible, in particular because it makes for unclear code and confusing situations like these. But if you really, truly had to assign values to a variable that is out of scope, you could use standard assignment inside eval:

a <- c(1,2,3)

eval(a[3] <- 4, envir = -1)

a
[1] 1 2 4

To generalize this further (if performing the assignment inside a function), you may need to use <<- inside eval anyway.

While changing variables out of scope is still a bad idea, using eval at least makes the operation more explicit, since you have to specify the environment in which the expression is to be evaluated.

All that said, scope-breaking assignments are never necessary, per se, and you should perhaps find a way to write your script such that this is not relied on.

jdobres
  • 11,339
  • 1
  • 17
  • 37
  • Hmm. Strangely, changing the `eval` statement to use `<<-` solves the issue. Yet another reason why superassignment is confusing. – jdobres Dec 14 '18 at 13:26
  • A way to fix the issue raised by @IceCreamToucan systematically might go something like `f <- function(object, index, value) { elements <- sapply(sys.call()[-1], as.character); call_text <- paste0(elements[1], "[", elements[2], "] <- ", elements[3]); eval(parse(text = call_text), envir = .GlobalEnv) }` – duckmayr Dec 14 '18 at 13:56
  • I am not sure why this works, but it does! Thanks for the help! I was indeed looking for an assignment within a function – rickwol Dec 17 '18 at 08:52
  • "I am not sure why this works, but it does" should be interpreted as a warning, and an incentive to consider writing code in a way that does make sense to you. My answer may be correct, but super assignment in R is still a bad idea. – jdobres Dec 18 '18 at 16:44