我根据subset()
编写了以下函数,我发现它很方便:
ss <- function (x, subset, ...)
{
r <- eval(substitute(subset), data.frame(.=x), parent.frame())
if (!is.logical(r))
stop("'subset' must be logical")
x[r & !is.na(r)]
}
所以,我可以写:
ss(myDataFrame$MyVariableName, 500 < . & . < 1500)
而不是
myDataFrame$MyVariableName[ 500 < myDataFrame$MyVariableName
& myDataFrame$MyVariableName < 1500]
这似乎是其他人可能已经开发出的解决方案 - 包括核心R中我可能错过的东西。什么东西已经存在?
答案 0 :(得分:4)
我意识到Ken提供的解决方案比仅选择范围内的项目更通用(因为它应该适用于任何逻辑表达式)但这确实提醒我Greg Snow在他的Teaching Demos包中有比较中缀运算符:
library(TeachingDemos)
x0 <- rnorm(100)
x0[ 0 %<% x0 %<% 1.5 ]
答案 1 :(得分:2)
感谢分享Ken。
您可以使用:
x <- myDataFrame$MyVariableName; x[x > 100 & x < 180]
您可能需要更少的输入,但如果您共享代码,则代码不太通用。我有一些节省时间的功能,但我们谨慎使用它们,因为它们可能会减慢您的代码速度(额外的步骤),并且当您与其他人共享文件时,还需要包含该功能的代码。
比较写作长度。几乎相同的长度:
ss(mtcars$hp, 100 < . & . < 180)
x <- mtcars$hp; x[x > 100 & x < 180]
比较1000次重复的时间。
library(rbenchmark)
benchmark(
tyler = x[x > 100 & x < 180],
ken = ss(mtcars$hp, 100 <. & . < 180),
replications=1000)
test replications elapsed relative user.self sys.self user.child sys.child
2 ken 1000 0.56 18.66667 0.36 0.03 NA NA
1 tyler 1000 0.03 1.00000 0.03 0.00 NA NA
所以我想这取决于你是否需要速度和/或可用性与方便性。如果它仅适用于小型数据集,我会说它很有价值。
编辑:新基准
> benchmark(
+ tyler = {x <- mtcars$hp; x[x > 100 & x < 180]},
+ ken = ss(mtcars$hp, 100 <. & . < 180),
+ ken2 = ss2(mtcars$hp, 100 <. & . < 180),
+ joran = with(mtcars,hp[hp>100 & hp< 180 ]),
+ replications=10000)
test replications elapsed relative user.self sys.self user.child sys.child
4 joran 10000 0.83 2.677419 0.69 0.00 NA NA
2 ken 10000 3.79 12.225806 3.45 0.02 NA NA
3 ken2 10000 0.67 2.161290 0.35 0.00 NA NA
1 tyler 10000 0.31 1.000000 0.20 0.00 NA NA