Here are some possibilities:
myfilter1 <- function(data, condition) {
do.call(subset, list(data, substitute(condition)), envir = parent.frame())
}
myfilter1(iris, Sepal.Length > 7.1)
myfilter2 <- function(data, condition) {
eval.parent(substitute(with(data, data[condition, ])))
}
myfilter2(iris, Sepal.Length > 7.1)
library(gtools)
myfilter3 <- defmacro(data, condition, expr = {
with(data, data[condition, ])
})
myfilter3(iris, Sepal.Length > 7.1)
Read R source code associated with an S3 generic
To read the source R code for the methods of an S3 generic f first list the methods:
methods(f)
and then if f.x is one of the methods listed enter its name without parentheses into R:
f.x
or if that does not work (which would be the case if there is a * after the name in the methods output) then
getAnywhere("f.x")
If the code is in package p on CRAN then we could google for cran p and download its source from the package's CRAN home page or find it on github by googling for cran github p and look at the source on the github web site.
Performance
Regarding performance this is what I get on my PC:
library(dplyr)
library(gtools)
library(microbenchmark)
f1 <- function() {
len <- 7.1
myfilter1(iris, Sepal.Length > len)
}
f2 <- function() {
len <- 7.1
myfilter2(iris, Sepal.Length > len)
}
f3 <- function() {
len <- 7.1
myfilter3(iris, Sepal.Length > len)
}
fd <- function() {
len <- 7.1
filter(iris, Sepal.Length > len)
}
microbenchmark(f1(), f2(), f3(), fd())
giving the following.
Unit: microseconds
expr min lq mean median uq max neval cld
f1() 399.2 433.70 497.133 482.00 518.85 1362.6 100 b
f2() 301.4 326.15 374.078 364.50 407.65 579.1 100 a
f3() 302.4 330.65 375.650 352.25 397.15 623.0 100 a
fd() 1791.5 1948.60 2166.466 2117.35 2262.65 3443.7 100 c
myfilter2 and myfilter3 have about the same mean times and both are faster than the other two.