Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Error - cannot change value of locked binding for 'df'

Tags:

r

I'm trying to filter some data, with functions in R relatives to data frames. But in the second function, it gives me the following error: cannot change the value of locked binding for df. Can anyone help me please?

Btw, this is the code:

load.data = function(x,dir = ".") {
dados_reais <<- read.csv(paste(dir,x,sep="/"), header = FALSE, sep = "\t", dec = ".", col.names = c("Seq","Allele","Peptide","Identity","Pos","Core","Core-Rel", "Um-log50k(aff)","Affinity(nM)","Rank","Exp_Bind","Binding Level"))
}

filter.data = function(x, dir = ".") {load.data(x, dir) df <<- dados_reais[,c(1,2,3,4,9,10,12)}
like image 871
João Fernandes Avatar asked Jun 22 '17 14:06

João Fernandes


2 Answers

Answer:

The reason is that <<- and <- work differently.

x <- val means "assign the value val to the name x in the current scope." That's the assignment operator you should usually use.

x <<- val means "go search for a name x in the current scope and its enclosing scopes. As soon as you find it, assign the value val to it and stop. If you don't find it, create a new variable x in the broadest scope (global) and assign it the value val."

In your case, your name choice of df was somewhat unlucky: there's a built-in function df (in the stats namespace) for computing the density of Snedecor's F distribution function. Your <<- assignment found that, tried to change its value to dados_reais[,c(1,2,3,4,9,10,12)], and refused (because the built-in df function is "locked", i.e. immutable). An easier example showing the issue is this:

df <<- 5
# Error: cannot change value of locked binding for 'df'

Incidentally:

As demonstrated, R's variables and functions share the same namespaces (or, more accurately: R's functions are typically stored in the same symbol tables [environments] that all the other variables are, they're not "special" like in many other languages). So does that mean that you shouldn't ever use a variable like df or min or q or t, that clashes with a built-in function's name? No, generally it's not a big deal, because when you do min(x), R knows to look for a function called min, not any old symbol table entry called min, so it uses something like get("min", mode="function") to make sure it doesn't accidentally find some variable you've defined that happens to be called min.

That said, sometimes you do get some name collisions that are a little sneaky. For example, if you think you have a data.frame called df, but you forgot to actually create it, you might see an error like this:

df[1, 5]
# Error in df[1, 5] : object of type 'closure' is not subsettable

It's saying that the function df (a function in R is an "object of type 'closure'") can't be indexed with square brackets like that. File that somewhere in your brain, because if you work with R long enough, you're bound to see that error once in a while.

like image 55
Ken Williams Avatar answered Oct 21 '22 04:10

Ken Williams


You should be avoiding <<-. That creates function with side-effects which run contrary to the spirit of functional languages. Try

load.data <- function(x,dir = ".") {
    read.csv(paste(dir,x,sep="/"), header = FALSE, sep = "\t", dec = ".", col.names = c("Seq","Allele","Peptide","Identity","Pos","Core","Core-Rel", "Um-log50k(aff)","Affinity(nM)","Rank","Exp_Bind","Binding Level"))
}

filter.data <- function(x, dir = ".") {
    load.data(x, dir)[,c(1,2,3,4,9,10,12)]
}

df <- filter.data("mypath.csv")
like image 24
MrFlick Avatar answered Oct 21 '22 05:10

MrFlick