我遇到了一个令人困惑的子集功能"功能"(使用列名作为子集的矢量名称不起作用):
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])
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,这里发生了什么以及为什么?
subset()首先会在数据框中查看您提到的任何对象,因此在您的第一个示例中Species[i]返回'setosa'(与之相同iris$Species[i]).只有在数据框内找不到您指定的对象时,R才会查看父框架并在那里找到正确的对象.
所以这一切都有效,你只是不明白它是如何工作的.您可以在帮助文件中阅读此内容:
请注意,子集将在数据框中进行评估,因此可以将列引用(通过名称)作为表达式中的变量(请参阅示例).
这是怎么发生的?
原因是以下代码行subset():
e <- substitute(subset)
r <- eval(e, x, parent.frame())
Run Code Online (Sandbox Code Playgroud)
subset(或e)在你的例子中Species == Species[i]x 在你的例子中 irisparent.frame() 在您的示例中返回全局环境.调用的第二个参数eval,x称为envir.它是评估表达式的环境(或列表或数据框,...).在您的情况下,R评估Species == Species[i] 内部 x,这是您的数据框架.
第三个参数parent.frame()是封闭.这是包含您指定的环境的数据框的环境,并且是在数据框中找不到变量的情况下R将查看的位置.
也可以看看 ?eval