我试图过滤一些数据,使用R中与 Dataframe 相关的函数。但是在第二个函数中,它给出了以下错误:无法更改df
的锁定绑定的值。有人能帮帮我吗?
顺便说一句,代码如下:
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)}
4条答案
按热度按时间ndasle7k1#
回答:
原因是
<<-
和<-
的工作方式不同。x <- val
表示“将值val
赋给当前作用域中的名称x
”。这是您通常应该使用的赋值运算符。x <<- val
表示“在当前作用域及其封闭作用域中搜索名称x
。一旦找到它,就将值val
赋给它并停止。如果找不到,则在最大范围(全局)内创建一个新变量x
,并为其赋值val
。在你的例子中,你选择的
df
有点不吉利:有一个内置函数df
(在stats
命名空间中)用于计算Snedecor's F distribution function的密度。您的<<-
赋值发现,试图将其值更改为dados_reais[,c(1,2,3,4,9,10,12)]
,但被拒绝(因为内置的df
函数被“锁定”,即不可变)。一个更简单的例子说明了这个问题:顺便说一句:
如图所示,R的变量和函数共享相同的命名空间(或者更准确地说:R的函数通常存储在与所有其他变量相同的符号表[环境]中,它们不像许多其他语言那样“特殊”。那么,这是否意味着你不应该使用像
df
或min
或q
或t
这样的变量,这些变量与内置函数的名称冲突?不,一般来说这不是什么大问题,因为当你执行min(x)
时,R知道要查找一个名为min
的 * 函数 *,而不是任何名为min
的旧符号表条目,所以它使用类似get("min", mode="function")
的东西来确保它不会意外地找到你定义的某个变量,而这个变量恰好被称为min
。也就是说,有时你确实会遇到一些名称冲突,这有点鬼鬼祟祟。例如,如果你认为你有一个名为
df
的data.frame
,但你忘记了实际创建它,你可能会看到这样的错误:它是说函数
df
(R中的函数是“闭包类型的对象”)不能用这样的方括号索引。把它记在你的脑子里,因为如果你使用R语言的时间足够长,你肯定会偶尔看到这个错误。dbf7pr2w2#
你应该避免
<<-
。这就产生了带有副作用的函数,这与函数式语言的精神背道而驰。试试看ie3xauqp3#
有时候,人们确实想违背函数式语言的精神。
我不知道为什么,在R中,一个锁定的 * 函数 * 阻止你在同一级别创建一个 * 变量 *,但OP的问题是因为 * 函数 *
df()
被锁定在一个高于当前环境的环境中(<<-
找到了)。下面是一些代码(可能不是最好的),用于查找
df
(已经)绑定(即已经存在)的环境,然后检查它是否实际上锁定在该环境中。在这种情况下,在“全局”上下文中创建一个变量
df
应该可以解决这个问题。即,或者,更改变量的名称(比如从
df
更改为myveryowndf
)也应该可以解决这个问题。tez616oj4#
我在包内创建函数时遇到了这个问题,我在导出的函数内使用
<<-
来覆盖来自不同包的一些函数。我用env <- parent.env()
创建了hack,并将其添加到父env中,因为该函数总是在顶层调用。所以env将是调用函数的代码的范围,而不是包。下面是这个函数完整代码,它覆盖了shiny和当前的包函数:
使用
<<-
抛出此错误,因为您无法修改包范围。这个不管用
编辑:整个代码是由我工作的公司(Roche/Genentech)发布的,可以在GitHub上找到:Genentech/battery