为什么子集操作在向量名称与列名称相同时无法正常工作?

3

我发现 subset 函数有一个令人困惑的“特性”(使用列名作为向量名称进行子集操作无效):

data(iris)
Species <- unique(iris$Species)
i <- 2
Species[i]
subset(iris, subset = Species == Species[i])

sp <- unique(iris$Species)
sp[i]
subset(iris, subset = Species == sp[i])

有人能够解释一下这里发生了什么以及为什么会发生吗?

1个回答

10
subset()首先会在数据框中查找您提及的任何对象,因此在您的第一个示例中,Species[i]返回“setosa”(与iris$Species[i]相同)。 仅当您指定的对象无法在数据帧内找到时,R才会查找父框架并在那里找到正确的对象。
因此,这确实有效,您只是不理解它的工作原理。 您可以在帮助文件中阅读到这一点:
请注意,子集将在数据框中进行评估,因此列可以作为表达式中的变量(按名称)引用(请参见示例)。
这是如何发生的呢?
原因是在subset()中的以下代码行:
e <- substitute(subset)
r <- eval(e, x, parent.frame())
  • subset(或e)在您的示例中为Species == Species[i]
  • x在您的示例中为iris
  • parent.frame()在您的示例中返回全局环境。

调用eval的第二个参数x称为envir。它是表达式进行评估的环境(或列表或数据框等)。在您的情况下,R在x中(即您的数据框)内部评估Species == Species[i]

第三个参数parent.frame()是封闭环境。它是包围您指定的数据框作为环境的环境,并且是R在变量未在数据框中找到时查找的位置。

另请参见?eval


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接