Tomas
Tomas

Reputation: 59487

How to assign to global variable from a function when masking existing object?

I have function like this:

myfun <- function ()
{
    df <<- data.frame(a = 1)
}
myfun()

but it reports an error "Error in myfun() : cannot change value of locked binding for 'df'". I really need to modify the global variable df and I don't care if I mask existing function. How can I do this?

I discovered this solution. It works, but is there something less complicated?

myfun <- function ()
{
    df <- data.frame(a = 1)
    assign("df", df, envir = .GlobalEnv)
}
myfun()

Upvotes: 0

Views: 95

Answers (2)

Maurits Evers
Maurits Evers

Reputation: 50668

There's not much to add to @TimBiegeleisen's answer; however, in response to your post and the error you see, you'd need to declare df outside of the function scope.

The following works

df <- data.frame()
myfun <- function () df <<- data.frame(a = 1)
myfun()
df
#  a
#1 1

Note however that this is not how <<- is supposed to be used, see Dirk Eddelbuettel's answer to "What is the difference between assign and <<- in R". To summarise:

  • you may use <<- to update an object in a parent (but not global) environment ("super-assignment" with lexical scope), and conversely
  • don't use <<- to update an object in the global environment.

Upvotes: 3

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521179

The best solution here would be to avoid handling the scope of the variables inside the function entirely. If you want to create a function which can be used to assign a data frame variable, then just have that function return the data frame:

myfun <- function() {
    df <- data.frame(a = 1)
    return(df)
}

# from some calling scope
mydf <- myfun()

If you want a data frame to be assigned inside a certain scope, then let that scope make the assignment, rather than having the function do this.

Upvotes: 5

Related Questions