R错误-无法更改“df”的锁定绑定的值

esyap4oy  于 2023-06-03  发布在  其他
关注(0)|答案(4)|浏览(142)

我试图过滤一些数据,使用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)}
ndasle7k

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函数被“锁定”,即不可变)。一个更简单的例子说明了这个问题:

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

顺便说一句:

如图所示,R的变量和函数共享相同的命名空间(或者更准确地说:R的函数通常存储在与所有其他变量相同的符号表[环境]中,它们不像许多其他语言那样“特殊”。那么,这是否意味着你不应该使用像dfminqt这样的变量,这些变量与内置函数的名称冲突?不,一般来说这不是什么大问题,因为当你执行min(x)时,R知道要查找一个名为min的 * 函数 *,而不是任何名为min的旧符号表条目,所以它使用类似get("min", mode="function")的东西来确保它不会意外地找到你定义的某个变量,而这个变量恰好被称为min
也就是说,有时你确实会遇到一些名称冲突,这有点鬼鬼祟祟。例如,如果你认为你有一个名为dfdata.frame,但你忘记了实际创建它,你可能会看到这样的错误:

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

它是说函数df(R中的函数是“闭包类型的对象”)不能用这样的方括号索引。把它记在你的脑子里,因为如果你使用R语言的时间足够长,你肯定会偶尔看到这个错误。

dbf7pr2w

dbf7pr2w2#

你应该避免<<-。这就产生了带有副作用的函数,这与函数式语言的精神背道而驰。试试看

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")
ie3xauqp

ie3xauqp3#

有时候,人们确实想违背函数式语言的精神。
我不知道为什么,在R中,一个锁定的 * 函数 * 阻止你在同一级别创建一个 * 变量 *,但OP的问题是因为 * 函数 * df()被锁定在一个高于当前环境的环境中(<<-找到了)。
下面是一些代码(可能不是最好的),用于查找df(已经)绑定(即已经存在)的环境,然后检查它是否实际上锁定在该环境中。

> x <- environment(); while(TRUE) { print(exists("df", x)); x <- parent.env(x) }
[1] TRUE
[1] TRUE
[1] TRUE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
Error in parent.env(x) : the empty environment has no parent
> bindingIsLocked("df", parent.env(parent.env(environment())))
[1] TRUE
>

在这种情况下,在“全局”上下文中创建一个变量df应该可以解决这个问题。即,

df <- NULL

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

或者,更改变量的名称(比如从df更改为myveryowndf)也应该可以解决这个问题。

tez616oj

tez616oj4#

我在包内创建函数时遇到了这个问题,我在导出的函数内使用<<-来覆盖来自不同包的一些函数。我用env <- parent.env()创建了hack,并将其添加到父env中,因为该函数总是在顶层调用。所以env将是调用函数的代码的范围,而不是包。
下面是这个函数完整代码,它覆盖了shiny和当前的包函数:

#' @export
useMocks <- function() {
  observeEvent <- battery::observeEventMock
  assignInNamespace("observeEvent", observeEvent, "battery")
  assignInNamespace("observeEvent", observeEvent, "shiny")
  isolate <- battery::isolate
  assignInNamespace("isolate", isolate, "shiny")
  makeReactiveBinding <- battery::makeReactiveBinding
  assignInNamespace("makeReactiveBinding", makeReactiveBinding, "shiny")
  renderUI <- battery::renderUI
  assignInNamespace("renderUI", renderUI, "shiny")
  ## we modify the parent frame so it update environment when function is called not the package
  env <- parent.frame()
  env$observeEvent <- observeEvent
  env$isolate <- isolate
  env$renderUI <- renderUI

}

使用<<-抛出此错误,因为您无法修改包范围。

observeEvent <<- battery::observeEventMock

这个不管用

编辑:整个代码是由我工作的公司(Roche/Genentech)发布的,可以在GitHub上找到:Genentech/battery

相关问题