R中向量的子集()

Ken*_*ams 6 r subset

我已经编写了以下函数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)]
}
Run Code Online (Sandbox Code Playgroud)

所以,我可以写:

ss(myDataFrame$MyVariableName, 500 < . & . < 1500)
Run Code Online (Sandbox Code Playgroud)

代替

myDataFrame$MyVariableName[ 500 < myDataFrame$MyVariableName 
                                & myDataFrame$MyVariableName < 1500]
Run Code Online (Sandbox Code Playgroud)

这似乎是其他人可能已经为其开发的解决方案 - 包括核心RI中可能遗漏的内容.那里有什么东西吗?

Tyl*_*ker 2

感谢分享肯。

你可以使用:

x <- myDataFrame$MyVariableName; x[x > 100 & x < 180] 
Run Code Online (Sandbox Code Playgroud)

您的代码可能需要较少的输入,但如果您共享代码,则代码对其他人来说不太通用。我自己有一些类似的节省时间的函数,但要谨慎使用它们,因为它们可能会减慢您的代码速度(额外的步骤),并且要求您在与其他人共享文件时也包含该函数的代码。

比较书写长度。几乎相同的长度:

ss(mtcars$hp, 100 < . & . < 180)
x <- mtcars$hp; x[x > 100 & x < 180] 
Run Code Online (Sandbox Code Playgroud)

比较 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
Run Code Online (Sandbox Code Playgroud)

所以我想这取决于您是否需要速度和/或可共享性与便利性。如果它只适合你的小数据集,我会说它很有价值。

编辑:新基准

> 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
Run Code Online (Sandbox Code Playgroud)