我正在try 为我的定制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中的data.frame的内容设置类的子集,我定义了以下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

但是,当我try 在另一个函数中运行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

这似乎是环境的问题,但我不知道到底是哪里出了问题.有没有人有建议如何避免这个错误?

推荐答案

我刚刚找到了thisthis,它们似乎一起回答了我的问题.该问题与S4类的使用无关,而是由subset确定变量作用域的方式引起的.最初,我对subset的定义是在x@data对象中查找let.通过专门定义在x@data的范围内对表达式求值,但允许将范围扩展到parent.frame()(变量let所属的),解决了错误,并允许我根据需要设置子集.

以下是完整的代码:

# 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)))

# Define a subset method
setMethod("subset", signature(x = "myClass"), function(x, ...) {
  condition <- substitute(...)
  indices <- eval(condition, x@data, parent.frame())
  x@data <- x@data[indices, ]
  return(x)
})

# Suppose we want to subset to only retain entries with "A"
whichletter <- "A"

# What if we have a function that should pass the subsetting value to the subset
# function?
randomFunction <- function(object, let) {
  object_subsetted <- subset(object, Letter %in% let)
  return(object_subsetted)
}

# Test it (works now)
randomFunction(object = dat, let = "A")
randomFunction(object = dat, let = "B")
An object of class "myClass"
Slot "data":
  Letter Number
1      A      1
2      A      2

An object of class "myClass"
Slot "data":
  Letter Number
3      B      3

然而,正如@jdl所强调的那样,定义一个[方法可能更明智.

R相关问答推荐

仅返回R中所有其他列的列ID和年份缺失(NA)数据的列表

如何在列表的子元素上使用setName

在R中,将一个函数作为输入传递给另一个函数时进行参数判断

在特定列上滞后n行,同时扩展框架的长度

寻找图片边缘

在R底座中更改白天和夜晚的背景 colored颜色

terra nearest()仅为所有`to_id`列返回NA

隐藏e_mark_line的工具提示

使用ggsankey调整Sankey图中单个 node 上的标签

二维样条,严格以一个参数递增

将数据集中的值增加到当前包含的最大值

如何改变x轴比例的列在面

在R中,如何将变量(A,B和C)拟合在同一列中,如A和B,以及A和C在同一面板中?

使用rest从header(h2,h3,table)提取分层信息

R中的哈密顿滤波

Geom_Hline将不会出现,而它以前出现了

`夹心::vcovCL`不等于`AER::tobit`标准错误

如何在使用Alpha时让geom_curve在箭头中显示恒定透明度

网络抓取新闻标题和时间

排序R矩阵的行和列