便利そうなパッケージを教えてもらいました。

どうやら選択した行のパイプ%>%ごとの結果にView関数を適用してくれるRStudio addinのようです。

# devtools::install_github("daranzolin/ViewPipeSteps")
library(dplyr)
iris %>% 
  select(Species, Petal.Length) %>% 
  filter(Petal.Length > 1.6) %>% 
  group_by(Species) %>% 
  summarise(plsum = sum(Petal.Length))
# 上記4行を選択してAddinsボタンから「View Pipe Chain Steps」を選択

おー、便利そう。
ショートカットキー設定しておけば、こういうパイプごとの検証をマウス使わずに全部完結できますね。

では、このアドインの中で何が行われているのでしょうか?
Rフォルダの中を見てみたいと思います。

1. アドインの中身

まずはR/utils.Rを見てみましょう。

# 1~2要素目,1~3要素目といったパイプごとのまとまりを表すベクトルを返す
createCalls <- function(x) {
  # 空白除去
  x <- purrr::map_chr(x, stringr::str_trim)
  calls <- list()
  # group_by系は無視
  # パイプの区切りごとに"View("を足していく
  # ここがキーポイント
  for (i in 2:length(x)) {
    if (grepl("group_by", x[i])) next
    call <- paste(paste(x[1:i], collapse = " "), "View(")
    calls[[i]] <- call
  }
  # nullは除去
  invisible(purrr::discard(calls, is.null))
}
# View()で出てくるタブ名を生成
createViewTitles <- function(steps) {
  # group_by系を含む数を計算
  gbs <- sum(stringr::str_detect(steps, "group_by"))
  stepInds <- 2:(length(steps) - gbs)
  # 最初の要素は無視
  # それぞれの要素の関数名をとってくる
  steps <- tail(purrr::map(strsplit(steps, "\\("), `[[`, 1), -1) %>%
    purrr::discard(~grepl("group_by", .)) %>%
    purrr::map_chr(stringr::str_trim)
  sprintf("%s. %s", (stepInds - 1), steps)
}
createViews <- function(calls, titles) {
  # タイトルと閉じ括弧を追加
  calls <- sprintf("%s title = '%s')", calls, titles)
  # eval()の結果とエラーとメッセージをリストで返す関数を新たに作る
  safeEval <- purrr::safely(eval)
  # ここでcallsの各要素の内容を実行する
  cList <-  purrr::map(calls, ~safeEval(parse(text = .)))
  # エラーになった箇所を教えるメッセージを出力する
  for (i in seq_along(cList)) {
    if (!is.null(cList[[i]]$error)) {
      w <- sprintf("Pipe error at step %s: %s", titles[i], cList[[i]]$error)
      stop(w, call. = FALSE)
    }
  }
}

意外とシンプルな構成要素で出来てましたね。
これを利用して@hoxo_mさんがおっしゃってた zeallotパッケージを使ったc(N, M) %<-% dim(x)の形式に倣って、

c(SEL, FIL, SUM) %<-% hogehoge({
  iris %>% 
    select(Species, Petal.Length) %>% 
    filter(Petal.Length > 1.6) %>% 
    group_by(Species) %>% 
    summarise(plsum = sum(Petal.Length))
  })

↑みたいなことも出来そうですね。使いどころがあるかと言われると微妙ですが…。

次にR/viewPipeChain.Rを見てみます。

viewPipeChain <- function() {
  # 選択行の取得
  context <- rstudioapi::getActiveDocumentContext()
  # 改行\nの除去
  pc <- stringr::str_remove_all(context$selection[[1]]$text, "\n")
  #if (!grepl("%>%", pc)) stop("Must highlight a pipe sequence", call. = FALSE)
  # パイプ区切りにベクトル化
  pc <- paste(strsplit(pc, "%>%")[[1]], "%>%")
  # 上で説明した関数を実行していく
  pcTitles <- createViewTitles(pc)
  pcCalls <- createCalls(pc)
  createViews(pcCalls, pcTitles)
}

utils.Rで作成した関数を選択行に対して実行していく関数のようです。 rstudioapi::getActiveDocumentContext()は選択行(アクティブになっている行)に関する情報を格納してくれるもので、context$selection[[1]]$textに選択行が文字列として格納されます。これはggThemeAssistパッケージでも使われて、多くのアドインで使われている関数です。

2. まとめ

今回はパッケージの紹介と中身を見てみたということでこれで終わりです。