サーチ…


前書き

magrittrdplyr 、および他のRパッケージで利用可能なパイプ演算子は、より典型的な入れ子のRメソッドではなく、 dplyr演算子を使用して次のステップの入力として1つのステップの結果を渡すことによって一連の操作を使用してデータオブジェクトを処理します関数呼び出し。

パイプ演算子の意図された目的は、書かれたコードの人間の可読性を高めることです。パフォーマンスの考慮事項については、「注意事項」を参照してください。

構文

  • lhs%>%rhs# rhs(lhs)パイプ構文

  • lhs%>%rhs(a = 1) rhs(lhs, a = 1)パイプ構文rhs(lhs, a = 1)

  • lhs%>%rhs(a = 1、b =。)# rhs(a = 1, b = lhs)パイプ構文rhs(a = 1, b = lhs)

  • lhs%<>%rhs# lhs <- rhs(lhs)パイプ構文lhs <- rhs(lhs)

  • lhs%$%rhs(a) with(lhs, rhs(lhs$a))パイプ構文

  • lhs%T>%rhs# { rhs(lhs); lhs }パイプ構文{ rhs(lhs); lhs }

パラメーター

lhs rhs
値またはmagrittrプレースホルダー。 magrittrセマンティクスを使用した関数呼び出し

備考

%>%を使用するパッケージ

pipe演算子はmagrittrパッケージで定義されてmagrittrますが、 dplyrパッケージ( magrittrから定義をインポートします)で大きな可視性と人気を得ました。現在はtidyverse一部でtidyverse共通のデータ表現とAPI設計を共有しているため、調和して動作するパッケージのコレクションです。

magrittrパッケージには、化合物割り当てパイプ%<>% 、展示パイプ%$% 、ティーオペレータ%T>%など、配管の柔軟性を必要とする人にも、パイプ演算子のいくつかのバリエーションが用意されています。また、特別な構文( +[[[など])を持つ共通関数を置き換えることで、一連のパイプ内で簡単に使用できるエイリアス関数を提供します。

ドキュメントの検索

(のような任意の中置演算子と同じように+*^&%in%あなたが引用符でそれを置く場合)、あなたは公式ドキュメントを見つけることができます?'%>%'またはhelp('%>%') pkg:magrittrを添付したパッケージをロードしたと仮定します)。

ホットキー

Ctrl+Shift+MWindowsおよびLinux )、 Cmd+Shift+MMac )のパイプ演算子用の特別なホットキーがRStudioにあります。

パフォーマンスに関する考慮事項

パイプ演算子は便利ですが、主に使用時のオーバーヘッドによりパフォーマンスに悪影響が及ぶことに注意してください。パイプ演算子を使用するときは、次の2つの点を注意深く検討してください。

  • マシンパフォーマンス(ループ)
  • 評価( object %>% rm()object削除しません)

基本的な使用と連鎖

パイプ演算子%>%は、関数に引数を挿入するために使用されます。言語の基本機能ではなく、 magrittrなどのパッケージを提供した後にのみ使用できます。パイプ演算子は、パイプの左辺(LHS)をとり、パイプの右辺(RHS)の関数の最初の引数として使用します。例えば:

library(magrittr)

1:10 %>% mean
# [1] 5.5

# is equivalent to
mean(1:10)
# [1] 5.5

パイプを使用して、一連の関数呼び出しを置き換えることができます。複数のパイプを使用すると、内側から外側に向かって、左から右へ順番に読み書きを行うことができます。たとえば、要素として定義されているyearsがありますが、数値に変換する必要があるとします。情報が失われるのを防ぐため、まず文字に変換してから数値に変換します。

years <- factor(2008:2012)

# nesting
as.numeric(as.character(years))

# piping
years %>% as.character %>% as.numeric

RHS(右手側)の最初の引数としてLHS(左手側)を使用したくない場合は、引数の名前付けや使用などの回避策があります.パイプされた入力がどこに行くのかを示します。

# example with grepl
# its syntax:
# grepl(pattern, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)

# note that the `substring` result is the *2nd* argument of grepl
grepl("Wo", substring("Hello World", 7, 11))

# piping while naming other arguments
"Hello World" %>% substring(7, 11) %>% grepl(pattern = "Wo")

# piping with .
"Hello World" %>% substring(7, 11) %>% grepl("Wo", .)

# piping with . and curly braces
"Hello World" %>% substring(7, 11) %>% { c(paste('Hi', .)) }
#[1] "Hi World"

#using LHS multiple times in argument with curly braces and .
"Hello World" %>% substring(7, 11) %>% { c(paste(. ,'Hi', .)) }
#[1] "World Hi World"

機能配列

繰り返し使用する一連の手順を考えると、それを関数に格納すると便利なことがよくあります。パイプを使うと、次のようなドットでシーケンスを開始することで、このような関数を読み込み可能な形式で保存することができます。

. %>% RHS

たとえば、因子日付があり、その年を抽出したいとします。

library(magrittr) # needed to include the pipe operators
library(lubridate)
read_year <- . %>% as.character %>% as.Date %>% year

# Creating a dataset
df <- data.frame(now = "2015-11-11", before = "2012-01-01")
#          now     before
# 1 2015-11-11 2012-01-01

# Example 1: applying `read_year` to a single character-vector
df$now %>% read_year
# [1] 2015

# Example 2: applying `read_year` to all columns of `df`
df %>% lapply(read_year) %>% as.data.frame  # implicit `lapply(df, read_year)
#    now before
# 1 2015   2012

# Example 3: same as above using `mutate_all`
library(dplyr)
df %>% mutate_all(funs(read_year))
# if an older version of dplyr use `mutate_each`
#    now before
# 1 2015   2012

関数の名前を入力するかfunctionsを使用して、関数の構成を確認できます。

read_year
# Functional sequence with the following components:
# 
#  1. as.character(.)
#  2. as.Date(.)
#  3. year(.)
# 
# Use 'functions' to extract the individual functions. 

シーケンス内の位置によって各関数にアクセスすることもできます。

read_year[[2]]
# function (.) 
# as.Date(.)

一般に、このアプローチは、明瞭さが速度よりも重要である場合に有用であり得る。

%<>%での割り当て

magrittrパッケージには、最初に1つ以上のrhs式にパイプして値を更新し、結果を代入することによって値を更新する複合代入式演算子%<>%が含まれています。これにより、オブジェクト名を2回(代入演算子<- )の両側に1回ずつ入力する必要がなくなります。 %<>%はチェーン内の最初の中置演算子でなければなりません:

library(magrittr)
library(dplyr)

df <- mtcars

書くのではなく

df <- df %>% select(1:3) %>% filter(mpg > 20, cyl == 6)

または

df %>% select(1:3) %>% filter(mpg > 20, cyl == 6) -> df

複合代入演算子は、 dfパイプして再割り当てします。

df %<>% select(1:3) %>% filter(mpg > 20, cyl == 6)

%$%でコンテンツを公開する

展示パイプ演算子%$%は、左側のオブジェクト内のRシンボルとして列名を右側の式に公開します。この演算子は、 data引数を持たない(例えばlmとは異なり)引数としてdata.frameとcolumnの名前を取らない関数(ほとんどの主要なdplyr関数)にパイプするときに便利です。

展示パイプ演算子%$%使用すると、列名を参照する必要があるときにパイプラインを破ることを避けることができます。たとえば、data.frameをフィルタ処理し、cor.testを使用して2つの列に対して相関テストを実行するとしcor.test

library(magrittr)
library(dplyr)
mtcars %>%
  filter(wt > 2) %$%
  cor.test(hp, mpg)

#> 
#>  Pearson's product-moment correlation
#> 
#> data:  hp and mpg
#> t = -5.9546, df = 26, p-value = 2.768e-06
#> alternative hypothesis: true correlation is not equal to 0
#> 95 percent confidence interval:
#>  -0.8825498 -0.5393217
#> sample estimates:
#>        cor 
#> -0.7595673

ここで標準の%>%パイプはdata.frameをfilter()に渡し、 %$%パイプはカラム名をcor.test()公開します。

展示パイプは、ベースR with()関数のパイプ対応バージョンのように動作し、同じ左側オブジェクトが入力として受け入れられます。

dplyrとggplot2でパイプを使用する

%>%演算子を使用して、dplyr出力をggplotにパイプすることもできます。これにより、簡単にカスタマイズ可能な統一された探索データ解析(EDA)パイプラインが作成されます。このメソッドは、ggplotで内部的に集計を実行するよりも高速で、不要な中間変数を避けるという利点があります。

library(dplyr)
library(ggplot)


diamonds %>% 
    filter(depth > 60) %>% 
    group_by(cut) %>% 
    summarize(mean_price = mean(price)) %>% 
    ggplot(aes(x = cut, y = mean_price)) + 
        geom_bar(stat = "identity")

%T>%で副作用を作成する

Rの中には、保存、印刷、プロットなどの副作用があり、必ずしも意味のある値や望ましい値を返すとは限らない関数もあります。

%T>% (tee演算子)では、元のlhs値をそのまま維持したまま、副作用生成関数に値を転送することができます。言い換えれば、tee演算子は%>%ように動作しますが、戻り値はrhs関数/式の結果ではなく、 lhs自体である点が異なります。

例:オブジェクトを作成、パイプ、書き込み、返す。この例で%T>%代わりに%>%が使用された場合、変数all_lettersは、ソートされたオブジェクトの値ではなくNULLが含まれます。

all_letters <- c(letters, LETTERS) %>%
    sort %T>% 
    write.csv(file = "all_letters.csv")

read.csv("all_letters.csv") %>% head()
#   x
# 1 a
# 2 A
# 3 b
# 4 B
# 5 c
# 6 C

警告:名前のないオブジェクトをsave()パイプすると、名前付きのオブジェクトが生成され. load()を使用してワークスペースにロードされたとき。ただし、ヘルパー関数を使用した回避策(インラインで匿名関数として記述することもできます)が可能です。

all_letters <- c(letters, LETTERS) %>%
    sort %T>% 
    save(file = "all_letters.RData")

load("all_letters.RData", e <- new.env())

get("all_letters", envir = e)
# Error in get("all_letters", envir = e) : object 'all_letters' not found

get(".", envir = e)
#  [1] "a" "A" "b" "B" "c" "C" "d" "D" "e" "E" "f" "F" "g" "G" "h" "H" "i" "I" "j" "J" 
# [21] "k" "K" "l" "L" "m" "M" "n" "N" "o" "O" "p" "P" "q" "Q" "r" "R" "s" "S" "t" "T" 
# [41] "u" "U" "v" "V" "w" "W" "x" "X" "y" "Y" "z" "Z"

# Work-around
save2 <- function(. = ., name, file = stop("'file' must be specified")) {
  assign(name, .)
  call_save <- call("save", ... = name, file = file)
  eval(call_save)
}

all_letters <- c(letters, LETTERS) %>%
    sort %T>%
    save2("all_letters", "all_letters.RData")


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow