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)}
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'
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.
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With