请解释为什么会/不会发生以下错误:

ff = factor(1:3)
`[.factor`(ff) # okay
base::`[.factor`(ff)  # Error in NextMethod("[") : 'NextMethod' called from an anonymous function
f = `[.factor`; f(ff) # Error in NextMethod("[") : wrong value for .Method

推荐答案

这是一个令人惊讶的微妙而复杂的问题.

之所以base::`[.factor`(ff)不能工作,而`[.factor`(ff)`能工作,即使这两段代码从字面上调用the same function,是因为NextMethod的工作方式不寻常.TL;DR是`[.factor`是S symbol,而base::`[.factor` call.

当你调用NextMethod时,underlying C code会计算出它被调用的是context,如果不满足几个条件中的任何一个,它就会抛出一个错误.

其中一个条件是NextMethod所在的函数必须被直接调用--从技术上讲,调用中的第一个 node 必须是symbol,而不是表达式.如果您试图通过调用获取函数,NextMethod会检测到这一点,并给出"匿名函数"错误.

NextMethod还会判断函数的名称是否与正在使用的泛型一致,如果不匹配,我们会得到"错误的.Method的值"错误

我们可以用一个简单的例子来演示相同的行为.我们有一个"Foo"类的对象:

foo <- structure(1:3, class = c("foo"))

foo
#> [1] 1 2 3
#> attr(,"class")
#> [1] "foo"

我们希望能够设置"foo"的子集,以便"foo"的任何子集仍然属于"foo"类,但除此之外,我们希望使用与数字向量完全相同的子集设置规则.这就是NextMethod的用武之地:

`[.foo` <- function(obj, ind) {
  y <- NextMethod("[")
  class(y) <- "foo"
  y
}


foo[2]
#> [1] 2
#> attr(,"class")
#> [1] "foo"

它的工作方式与预期一致,直接调用它也是如此:

`[.foo`(foo, 2)
#> [1] 2

如果我们试图调用函数indirectly,比如通过get,那么NextMethod会抛出错误,因为get("[.foo")是一个call,而不是一个符号.

get("[.foo")(foo, 2)
#> Error in NextMethod("[") : 'NextMethod' called from an anonymous function

即使将调用包装在圆括号或花括号中也足以生成错误(因为这些括号实际上也是调用)

(`[.foo`)(foo, 2)
#> Error in NextMethod("[") : 'NextMethod' called from an anonymous function

{`[.foo`}(foo, 2)
#> Error in NextMethod("[") : 'NextMethod' called from an anonymous function

如果我们try 重命名该函数,得到的错误与您try 重命名[.factor时遇到的错误相同:

f <- `[.foo`

f(foo, 2)
#> Error in NextMethod("[") : wrong value for .Method

现在f至少是symbol,但它是wrong符号(f不是[)

最后一个谜题是为什么base::`[.factor`不是一个符号.这是因为在R中命名空间符号::实际上是call,所以base::`[.factor`实际上被解析为`::`(base, `[.factor`)

class(quote(base::`[.factor`))
#> [1] "call"

然而,没有命名空间标识符,我们得到的是symbol(也就是"姓名")

class(quote(`[.factor`))
#> [1] "name"

R相关问答推荐

根据列表中项目的名称多次合并数据框和列表

MCMC和零事件二元逻辑回归

如何使用`ggplot2::geom_segment()`或`ggspatial::geom_spatial_segment()`来处理不在格林威治中心的sf对象?

在垂直轴中包含多个ggplot2图中的平均值

如何动态更新selectizeInput?

如果第一个列表中的元素等于第二个列表的元素,则替换为第三个列表的元素

在使用bslb和bootstrap5时,有没有办法更改特定dt行的 colored颜色 ?

在不丢失空值的情况下取消列出嵌套列表

KM估计的差异:SvyKm与带权重的调查

按列中显示的配对组估算NA值

在R中,如何将误差条放置在堆叠的每个条上?

将工作目录子文件夹中的文件批量重命名为顺序

如何在R中使用混合GAM模型只对固定的影响因素进行适当的预测?

基于R中的辅助向量中的值有条件地连接向量中的字符串

我需要使用ggplot2制作堆叠条形图

访问数据帧中未定义的列时出现R错误

在具有条件的循环中添加行

从data.table列表中提取特定组值,并在R中作为向量返回

Data.table条件合并

R data.设置函数&;连接中的列值而不使用for循环的表方法?