簡體   English   中英

如何覆蓋magrittr管道操作符?

[英]How to override magrittr pipe operator?

假設我有一個數據集,我想使用管道語法對它應用幾個過濾器,如下所示:

library(magrittr)
library(dplyr)
mtcars %<>% 
  filter(cyl == 4) %>% 
  select(cyl, mpg)
nrow(mtcars)
#[1] 11

我在每個這樣的步驟之后用nrow檢查數據集的當前狀態,所以我認為我可以覆蓋管道%<>%運算符沿着

`%<?>%` <- function(lhs, rhs) {
  x <- magrittr::`%<>%`(lhs, rhs)
  if (is.data.frame(x) & pipeVerbose) print(nrow(x))
}
#Using this will generate errors like
#Error in pipes[[i]] : subscript out of bounds

現在通過打開或關閉pipeVerbose標志,我將控制整個流程的跟蹤過程。 顯然,由於內部評估機制,這並不是那么簡單,如此處所示 問題是,是否有可能以最小的努力實現所需的行為,即無需修補magittr內部結構?

我不得不承認整個想法有點令人不安,但我的實際情況有點復雜,我想通過一個簡單的開/關開關來隱藏一些調試/開發細節以用於演示目的。

您可以使用TaskCallback ,它在頂級任務完成時執行。 在回調檢查中,表達式是否包含%<>%運算符,如果是,則打印結果:

printAssignmentPipe <- function(exp, res, success, printed){

  if (any(grepl("%<>%", exp, fixed = T))) {
    print(res)
  }
  TRUE
}

addTaskCallback(printAssignmentPipe)

您可以輕松擴展回調以檢查pipeVerbose的值,或者只需調用addTaskCallbackremoveTaskCallback來激活/取消激活。

由於鏈條利用了懶惰的評估,更好的翻譯會是這樣的:

`%<?>%` <- function(lhs, rhs) {
  call <- match.call()
  call[[1]] <- quote(`%<>%`)
  x <- eval.parent(call)
  if (is.data.frame(x) & pipeVerbose) print(nrow(x))
}

我們基本上重寫函數調用並對其進行評估。

請注意,您可以通過這種方式進行開/關切換,而不是比%<?>%而不是%<>%更明顯:

p <- function(x){if(pipeVerbose) print(nrow(x))}

pipeVerbose <- FALSE
mtcars %<>% 
  filter(cyl == 4) %>% 
  select(cyl, mpg) %T>% p

rm(mtcars)
pipeVerbose <- TRUE
mtcars %<>% 
  filter(cyl == 4) %>% 
  select(cyl, mpg) %T>% p

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM