为什么`[`比`subset`更好?

27 浏览
0 Comments

为什么`[`比`subset`更好?

当我需要过滤数据框,即提取符合某些条件的行时,我更喜欢使用subset函数:

subset(airquality, Month == 8 & Temp > 90)

而不是[函数:

airquality[airquality$Month == 8 & airquality$Temp > 90, ]

我喜欢使用的主要原因有两个:

  1. 我觉得代码从左到右阅读起来更好。即使不了解R的人也能看出上面的subset语句在做什么。
  2. 因为在select表达式中可以将列引用为变量,所以我可以省略几个按键。在上面的示例中,使用subset时,我只需要输入一次airquality,而使用[时需要输入三次。

因此,我一直使用subset,因为它更短更易读,甚至向其他R编码人员倡导其优美之处。但昨天我的世界崩溃了。当我阅读subset文档时,我注意到这个部分:

警告

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

有人可以帮忙澄清作者的意思吗?

首先,他们所说的“交互使用”是什么意思?我知道交互式会话是什么,就像批处理模式下运行的脚本一样,但我不明白它应该有什么区别。

然后,您能解释一下“参数subset的非标准评估”是什么意思,以及为什么它是危险的,可能提供一个示例吗?

admin 更改状态以发布 2023年5月23日
0
0 Comments

此外,[ 更快:

require(microbenchmark)        
microbenchmark(subset(airquality, Month == 8 & Temp > 90),airquality[airquality$Month == 8 & airquality$Temp > 90,])
    Unit: microseconds
                                                           expr     min       lq   median       uq     max neval
                     subset(airquality, Month == 8 & Temp > 90) 301.994 312.1565 317.3600 349.4170 500.903   100
     airquality[airquality$Month == 8 & airquality$Temp > 90, ] 234.807 239.3125 244.2715 271.7885 340.058   100

0
0 Comments

这个问题在评论中得到了@James很好的解答,他指出了Hadley Wickham在此处subset(以及类似它的函数)危险性的优秀解释。去看看吧!

这是一个有点长的阅读,因此记录下Hadley用来最直接回答“出了什么问题?”问题的例子可能是有帮助的:

Hadley提出了以下示例:假设我们想要使用以下函数对数据框进行子集和重新排序:

scramble <- function(x) x[sample(nrow(x)), ]
subscramble <- function(x, condition) {
  scramble(subset(x, condition))
}
subscramble(mtcars, cyl == 4)

这将返回错误:

Error in eval(expr, envir, enclos) : object 'cyl' not found

因为R不再“知道”如何找到名为“cyl”的对象。他还指出,如果恰好存在全局环境中叫做“cyl”的对象,那真正的奇怪事情就会发生:

cyl <- 4
subscramble(mtcars, cyl == 4)
cyl <- sample(10, 100, rep = T)
subscramble(mtcars, cyl == 4)

(运行它们并自己看看,非常疯狂。)

0