Suche…


Einführung

Pipe-Operatoren, die in magrittr , dplyr und anderen R-Paketen verfügbar sind, verarbeiten ein Datenobjekt unter Verwendung einer Folge von Operationen, indem das Ergebnis eines Schritts als Eingabe für den nächsten Schritt unter Verwendung von Infix-Operatoren anstelle der üblicheren R-Methode von verschachtelten übergeben wird Funktionsaufrufe.

Beachten Sie, dass das Ziel der Pipe-Operatoren darin besteht, die Lesbarkeit von geschriebenem Code für den Menschen zu verbessern. Weitere Informationen zur Leistung finden Sie im Abschnitt Anmerkungen.

Syntax

  • lhs%>% rhs # Pipe-Syntax für rhs(lhs)

  • lhs%>% rhs (a = 1) # Pipe-Syntax für rhs(lhs, a = 1)

  • lhs%>% rhs (a = 1, b =.) # rhs(a = 1, b = lhs) für rhs(a = 1, b = lhs)

  • lhs% <>% rhs # Pipe-Syntax für lhs <- rhs(lhs)

  • lhs% $% rhs (a) # Pipe-Syntax für with(lhs, rhs(lhs$a))

  • lhs% T>% rhs # Pipe-Syntax für { rhs(lhs); lhs }

Parameter

lhs rhs
Ein Wert oder der Magrittr-Platzhalter. Ein Funktionsaufruf unter Verwendung der Magrittr-Semantik

Bemerkungen

Pakete, die %>%

Der Pipe-Operator ist im magrittr Paket definiert, er gewann jedoch mit dem dplyr Paket (das die Definition aus magrittr ) große Sichtbarkeit und Beliebtheit. Jetzt ist es Teil von tidyverse , einer Sammlung von Paketen, die "harmonisch zusammenarbeiten, weil sie gemeinsame Datenrepräsentationen und API-Design verwenden" .

Das magrittr Paket bietet auch mehrere Variationen des Pipe-Operators für diejenigen, die mehr Flexibilität beim Paspeln wünschen, wie z. B. die zusammengesetzte Zuweisungspipe %<>% , die Expositionspipe %$% und den T-Operator %T>% . Es bietet auch eine Reihe von Alias-Funktionen, um gängige Funktionen mit einer speziellen Syntax ( + , [ , [[ usw.]) zu ersetzen, sodass sie problemlos innerhalb einer Pipeline-Kette verwendet werden können.

Dokumentation finden

Wie bei jedem Infix-Operator (wie + , * , ^ , & , %in% ) finden Sie die offizielle Dokumentation, wenn Sie sie in Anführungszeichen setzen:? ?'%>%' Oder help('%>%') ( Angenommen, Sie haben ein Paket geladen, das pkg:magrittr ) pkg:magrittr .

Hotkeys

In RStudio gibt es einen speziellen Hotkey für den Pipe-Operator: Ctrl+Shift+M ( Windows und Linux ), Cmd+Shift+M ( Mac ).

Überlegungen zur Leistung

Beachten Sie, dass der Pipe-Operator nützlich ist. Beachten Sie jedoch, dass die Leistung hauptsächlich durch den Overhead der Verwendung beeinträchtigt wird. Berücksichtigen Sie bei der Verwendung des Pipe-Operators die folgenden beiden Punkte sorgfältig:

  • Maschinenleistung (Schleifen)
  • Auswertung ( object %>% rm() entfernt object )

Grundlegende Verwendung und Verkettung

Der Pipe-Operator %>% wird verwendet, um ein Argument in eine Funktion einzufügen. Es ist keine magrittr der Sprache und kann nur verwendet werden, nachdem ein Paket, das es bereitstellt, wie z. B. magrittr , magrittr . Der Pipe-Operator nimmt die linke Seite (LHS) der Pipe und verwendet sie als erstes Argument der Funktion auf der rechten Seite (RHS) der Pipe. Zum Beispiel:

library(magrittr)

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

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

Die Pipe kann verwendet werden, um eine Folge von Funktionsaufrufen zu ersetzen. Mehrere Pipes ermöglichen das Lesen und Schreiben der Sequenz von links nach rechts und nicht von innen nach außen. Angenommen, wir haben years als Faktor definiert, möchten diesen jedoch in eine Zahl umwandeln. Um möglichen Informationsverlust zu vermeiden, konvertieren wir zuerst in Zeichen und dann in Zahlen.

years <- factor(2008:2012)

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

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

Wenn wir nicht möchten, dass die LHS (linke Seite) als erstes Argument auf der rechten Seite (rechte Seite) verwendet wird, gibt es Abhilfemaßnahmen, z . um anzugeben, wohin die Pipe-Eingabe geht.

# 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"

Funktionsabläufe

Bei einer Reihe von Schritten, die wir wiederholt verwenden, ist es oft praktisch, sie in einer Funktion zu speichern. Pipes ermöglichen das Speichern solcher Funktionen in einem lesbaren Format, indem eine Sequenz mit einem Punkt wie folgt gestartet wird:

. %>% RHS

Angenommen, wir haben Faktordaten und möchten das Jahr extrahieren:

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

Wir können die Zusammensetzung der Funktion überprüfen, indem Sie ihren Namen eingeben oder functions :

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

Wir können auf jede Funktion auch über ihre Position in der Reihenfolge zugreifen:

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

Im Allgemeinen kann dieser Ansatz nützlich sein, wenn Klarheit wichtiger ist als Geschwindigkeit.

Zuordnung mit% <>%

Das magrittr Paket enthält einen zusammengesetzten Zuweisungs-Infix-Operator %<>% , der einen Wert aktualisiert, indem er ihn zuerst in einen oder mehrere rhs Ausdrücke rhs und dann das Ergebnis zuweist. Dadurch müssen Sie den Objektnamen nicht zweimal eingeben (einmal auf jeder Seite des Zuweisungsoperators <- ). %<>% muss der erste Infix-Operator in einer Kette sein:

library(magrittr)
library(dplyr)

df <- mtcars

Anstatt zu schreiben

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

oder

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

Der zusammengesetzte Zuweisungsoperator leitet df sowohl weiter als auch neu:

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

Inhalte mit% $% verfügbar machen

Der Exposition-Pipe-Operator %$% macht die Spaltennamen als R-Symbole im linken Objekt für den Ausdruck auf der rechten Seite verfügbar. Dieser Operator ist praktisch , wenn in Funktionen Rohrleitungen, die keine haben data ( im Gegensatz zu , sagen wir, Argument lm ) und nehmen Sie nicht eine data.frame und Spaltennamen als Argumente ( die meisten der wichtigsten dplyr Funktionen).

Mit dem Exposition-Pipeline-Operator %$% kann ein Benutzer verhindern, dass eine Pipeline beschädigt wird, wenn auf Spaltennamen verwiesen werden muss. Angenommen, Sie möchten ein data.frame filtern und dann mit cor.test einen Korrelationstest für zwei Spalten 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

Hier durchläuft die standardmäßige Pipe %>% das data.frame an filter() , während die Pipe %$% die Spaltennamen für cor.test() .

Die Expositionspipe funktioniert wie eine Pipe-Version der Basis R with() Funktionen, und die gleichen Objekte auf der linken Seite werden als Eingaben akzeptiert.

Verwendung der Pipe mit Dplyr und ggplot2

Der Operator %>% kann auch verwendet werden, um die Ausgabe von dplyr an ggplot zu übergeben. Dadurch wird eine EDA-Pipeline (Unified Exploratory Data Analysis) geschaffen, die leicht anpassbar ist. Diese Methode ist schneller als die Aggregation intern in ggplot und hat den zusätzlichen Vorteil, dass unnötige Zwischenvariablen vermieden werden.

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")

Nebeneffekte mit% T>% erstellen

Einige Funktionen in R erzeugen einen Nebeneffekt (dh Speichern, Drucken, Plotten usw.) und geben nicht immer einen sinnvollen oder gewünschten Wert zurück.

%T>% (Abschlagoperator) können Sie einen Wert in eine Nebeneffektfunktion lhs wobei der ursprüngliche lhs Wert erhalten bleibt. Mit anderen Worten: Der Tee-Operator funktioniert wie %>% , nur dass die Rückgabewerte lhs selbst sind und nicht das Ergebnis der rhs Funktion / des rhs Ausdrucks.

Beispiel: Ein Objekt erstellen, übermitteln, schreiben und zurückgeben. Wenn in diesem Beispiel %>% anstelle von %T>% , enthält die Variable all_letters NULL und nicht den Wert des sortierten Objekts.

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

Warnung: Wenn Sie ein nicht benanntes Objekt an save() weiterleiten, wird ein Objekt mit dem Namen erzeugt . wenn mit load() in den Arbeitsbereich geladen. Eine Problemumgehung mithilfe einer Hilfsfunktion ist jedoch möglich (die auch als anonyme Funktion inline geschrieben werden kann).

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow