如何编写 dplyr::filter 函数

Sum*_*ing 0 r dplyr

dplyr过滤函数源代码,我无法得到,当我点击filter()时,源代码是UseMethod(),当我调试时,什么都没有出现;

我的测试代码:

过滤器(鸢尾花,萼片长度>7.1)

所以我尝试编写自己的函数

第一个版本:

   filter<-function(data,condition){
attach(data)
r<- data[which(condition,)]
detach(data)
return (r)
}
Run Code Online (Sandbox Code Playgroud)

它有效,当我使用 system.time() 比较 dplyr:filter 和 mine:filter 时,我的松散,比 dplyr 花费更多的时间;

第二个版本:

   filter<-function(data,condition){
r<-with(data,data[which(condition),])
return (r)
}
Run Code Online (Sandbox Code Playgroud)

它报告错误,未找到 Sepal.Length。

我知道是条件参数的问题,
如果我直接使用 with(irirs,irirs[which(Sepal.Length>7.1),]) ,它可以工作,但我需要一个自己的过滤器功能

我有两个问题:

  • 一种。如何编写有效的过滤器或修复我的第二个版本代码的问题。
  • 湾 如何读取函数源代码,如 usemethod("func")

多谢!

G. *_*eck 5

这里有一些可能性:

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

阅读与 S3 泛型相关的 R 源代码

要阅读 S3 泛型方法的源 R 代码,请f首先列出方法:

methods(f)
Run Code Online (Sandbox Code Playgroud)

然后如果f.x是列出的方法之一,将其名称不带括号输入 R:

f.x
Run Code Online (Sandbox Code Playgroud)

或者如果这不起作用(如果methods输出中的名称后面有 * 就是这种情况)然后

getAnywhere("f.x")
Run Code Online (Sandbox Code Playgroud)

如果代码在 CRAN 上的包 p 中,那么我们可以谷歌搜索cran p并从包的 CRAN 主页下载其源代码,或者通过谷歌搜索cran github p在 github 上找到它并查看 github 网站上的源代码。

表现

关于性能,这是我在 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())
Run Code Online (Sandbox Code Playgroud)

给出以下内容。

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

myfilter2并且myfilter3具有大致相同的平均时间并且两者都比其他两个快。