R 的 subset() 函数 [duplicate] 中的命名空间冲突

Namespace collision within R's subset() function [duplicate]

提问人:NicolasBourbaki 提问时间:5/4/2023 更新时间:5/4/2023 访问量:30

问:

我多次偶然发现 R 的子集函数的以下命名空间问题,我想在这里寻求一个比我更优雅的解决方案:

Species <- 'setosa'
subset(iris, Species==Species)

返回整个数据集,我认为是因为计算结果为 true。irisSpecies==Species

我的解决方案是

subset(iris, Species==get('Species', envir = .GlobalEnv)

但是,当变量仅在函数范围内定义时,这将不起作用。Species

当然,也可以使用不同的变量名称,例如(小写)作为全局变量。 但是,我认为这实际上可读性较差,作为最终用户,我实际上希望允许对来自不同命名空间的两个具有相同名称的变量进行这种比较。speciesR

R 命名空间 子集

评论

0赞 Gregor Thomas 5/4/2023
你的问题是什么?
0赞 Gregor Thomas 5/4/2023
请注意文档中的警告:“这是一个旨在以交互方式使用的便利功能。对于编程,最好使用标准子集函数,如 [,特别是参数子集的非标准计算可能会产生意想不到的后果。 是很早就涉足非标准评估。后来出现的软件包,如,以及晚的,如,建立在非标准评估思想的基础上,并将其细化到可以编程使用的程度,并有明确的方法来处理这样的情况。?subsetsubsetdata.tabledplyr

答:

2赞 MrFlick 5/4/2023 #1

基本 R 函数根本无法很好地处理相同变量名称的情况。我认为这是帮助页面包含以下警告的原因之一subsetsubset

这是一个旨在以交互方式使用的便利功能。对于编程,最好使用标准子集函数,如 [,特别是参数子集的非标准计算可能会产生意想不到的后果。

该消息基本上是建议您使用

iris[iris$Species==Species, ]

另一种方法是使用该函数来获取全局环境get()globalenv()

subset(iris, Species==globalenv()$Species)

如果您使用的是 dplyrs 函数,有一种方法可以明确使用代词filter().env

dplyr::filter(iris, Species==.env$Species)

评论

0赞 NicolasBourbaki 5/9/2023
非常感谢您的回答,这对我非常有帮助。我一直认为为了方便起见,会提供方括号语法作为函数的替代方案。很高兴知道它实际上是相反的。subset()
0赞 moodymudskipper 5/10/2023
我们也可以在函数中定义,然后我们可以使用 dplyr 的语法。 如果 Species 在任一侧都是 NA,可能会返回不同的内容。.env <- environment()subset()iris[iris$Species==Species, ]