我正在尝试为我的自定义 S4 类定义一个
subset
方法。虽然当我直接向 subset
提供子集设置标准时,子集设置按预期工作,但每当我在另一个函数中调用该方法时,该方法都会失败,其中子集设置标准从该函数传递到 subset
。
S4 类
myClass
由单个 data.frame
组成:
# Define class
setClass("myClass", slots = c(data = "data.frame"))
# Initiate a myClass object
dat <- new("myClass", data = data.frame(Letter = c("A", "A", "B"), Number = c(1, 2, 3)))
为了能够根据插槽
data.frame
中 data
的内容对类进行子集化,我定义了以下 subset
方法:
setMethod("subset", signature(x = "myClass"), function(x, ...) {
x@data <- subset(x@data, ...)
return(x)
})
该方法在调用时按预期工作,如下所示:
# Assume we only want to retain entries containing the letter "A"
whichletter <- "A"
# Subset (does work)
subset(dat, Letter %in% whichletter)
An object of class "myClass"
Slot "data":
Letter Number
1 A 1
2 A 2
但是,当我尝试在另一个函数中运行
subset
时,子集标准是通过该函数的参数提供的,子集设置将不起作用:
# Random function that takes a letter `let`as argument
randomFunction <- function(object, let) {
object_subsetted <- subset(object, Letter %in% let)
return(object_subsetted)
}
# Subset (does not work)
randomFunction(object = dat, let = whichletter)
Error in Letter %in% let: object 'let' not found
这似乎是环境问题,但我无法弄清楚到底出了什么问题。有人建议如何避免此错误吗?
这是答案的一部分。我觉得这很奇怪,但显然与未命名的参数混在一起,允许
eval
当从 subset
调用时可以按需要工作。
在调试模式下,我输入了两个命令。结果如下:
Browse[2]> subset(object@data,Letter %in% let, envir='CurrentEnvironment')
Letter Number
1 A 1
2 A 2
Warning message:
In subset.data.frame(object@data, Letter %in% let, envir = "CurrentEnvironment") :
extra argument ‘envir’ will be disregarded
Browse[2]> subset(object, Letter %in% let)
Error in eval(e, x, parent.frame()) : object 'let' not found
我这样做是因为当你的函数失败时我运行了
traceback
:
Rgames> randomFunction(object = dat, let = whichletter)
Error in eval(e, x, parent.frame()) : object 'let' not found
Rgames> traceback()
9: Letter %in% let
8: eval(e, x, parent.frame())
7: eval(e, x, parent.frame())
6: subset.data.frame(x@data, ...)
5: subset(x@data, ...)
4: subset(x@data, ...) at #2
3: subset(object, Letter %in% let)
2: subset(object, Letter %in% let) at #4
1: randomFunction(object = dat, let = whichletter)
因此,这意味着
subset.data.frame
无法正确地将 let
传递给 eval
调用——或者也许您需要传递像 这样的参数
subset(object, Letter %in% let, parent.frame(2))
我还没有测试过;我会让那些比我进一步评论更熟悉环境的人通过。我的猜测是,方法
subset.data.frame
不“高兴”传递额外的参数?