我遇到了一个令人困惑的子集功能“功能”(使用列名作为子集的矢量名称不起作用):
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])
有人可以解释一下,这里发生了什么以及为什么?
答案 0 :(得分:9)
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评估 Species == Species[i]
内的x
,这是您的数据框架。
第三个参数parent.frame()
是附件。这是包含您指定的环境的数据框的环境,并且是在数据框中找不到变量时R将查看的位置。
另见?eval