Zoeken…


Invoering

magrittr , beschikbaar in magrittr , dplyr en andere R-pakketten, verwerken een data-object met een reeks bewerkingen door het resultaat van de ene stap als invoer voor de volgende stap door te geven met infix-operators in plaats van de meer typische R-methode van genest functie oproepen.

Merk op dat het beoogde doel van pijpexploitanten is om de leesbaarheid van geschreven code door mensen te verbeteren. Zie het gedeelte Opmerkingen voor prestatieoverwegingen.

Syntaxis

  • lhs%>% rhs # pijpsyntaxis voor rhs(lhs)

  • lhs%>% rhs (a = 1) # pijpsyntaxis voor rhs(lhs, a = 1)

  • lhs%>% rhs (a = 1, b =.) # syntaxis van de pijp voor rhs(a = 1, b = lhs)

  • lhs% <>% rhs # pijpsyntaxis voor lhs <- rhs(lhs)

  • lhs% $% rhs (a) # pipe-syntaxis voor with(lhs, rhs(lhs$a))

  • lhs% T>% rhs # pijpsyntaxis voor { rhs(lhs); lhs }

parameters

lhs rhs
Een waarde of de tijdelijke aanduiding voor magrittr. Een functieaanroep met behulp van de semantiek van magrittr

Opmerkingen

Pakketten die %>%

De magrittr is gedefinieerd in het magrittr pakket, maar het kreeg een enorme zichtbaarheid en populariteit met het dplyr pakket (dat de definitie uit magrittr ). Nu maakt het deel uit van tidyverse , een verzameling pakketten die "in harmonie werken omdat ze gemeenschappelijke gegevensrepresentaties en API-ontwerp delen" .

Het magrittr pakket biedt ook verschillende variaties van de magrittr voor degenen die meer flexibiliteit in leidingen willen, zoals de samengestelde toewijzingspijp %<>% , de expositiepijp %$% en de tee-operator %T>% . Het biedt ook een reeks aliasfuncties ter vervanging van algemene functies met een speciale syntaxis ( + , [ , [[ , enz.) Zodat ze gemakkelijk kunnen worden gebruikt in een reeks pijpen.

Documentatie zoeken

Zoals bij elke infix-operator (zoals + , * , ^ , & , %in% ), kunt u de officiële documentatie vinden als u deze tussen aanhalingstekens plaatst ?'%>%' Of help('%>%') ( ervan uitgaande dat u een pakket hebt geladen dat pkg:magrittr hecht pkg:magrittr ).

sneltoetsen

Er is een speciale sneltoets in RStudio voor de pijpexploitant : Ctrl+Shift+M ( Windows & Linux ), Cmd+Shift+M ( Mac ).

Prestatieoverwegingen

Hoewel de pijpexploitant nuttig is, moet u zich ervan bewust zijn dat er een negatieve invloed is op de prestaties, voornamelijk vanwege de overhead van het gebruik ervan. Overweeg de volgende twee dingen zorgvuldig bij het gebruik van de buisoperator:

  • Machineprestaties (lussen)
  • Evaluatie ( object %>% rm() verwijdert geen object )

Basisgebruik en ketting

De pijpexploitant, %>% , wordt gebruikt om een argument in een functie in te voegen. Het is geen magrittr van de taal en kan alleen worden gebruikt na het koppelen van een pakket dat dit biedt, zoals magrittr . De pijpexploitant neemt de linkerkant (LHS) van de pijp en gebruikt deze als het eerste argument van de functie aan de rechterkant (RHS) van de pijp. Bijvoorbeeld:

library(magrittr)

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

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

De pijp kan worden gebruikt om een reeks functieaanroepen te vervangen. Met meerdere pijpen kunnen we de volgorde van links naar rechts lezen en schrijven, in plaats van van binnen naar buiten. Stel bijvoorbeeld dat we years als een factor hebben gedefinieerd, maar deze willen omzetten in een cijfer. Om mogelijk informatieverlies te voorkomen, converteren we eerst naar karakter en vervolgens naar numeriek:

years <- factor(2008:2012)

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

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

Als we niet willen dat de LHS (linkerkant) wordt gebruikt als het eerste argument op de RHS (rechterkant), zijn er tijdelijke oplossingen, zoals het benoemen van de argumenten of het gebruik . om aan te geven waar de leidinginvoer naartoe gaat.

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

Functionele sequenties

Gezien een reeks stappen die we herhaaldelijk gebruiken, is het vaak handig om het in een functie op te slaan. Met pijpen kunnen dergelijke functies in een leesbaar formaat worden opgeslagen door een reeks met een punt te starten zoals in:

. %>% RHS

Stel bijvoorbeeld dat we factordata hebben en het jaar willen extraheren:

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

We kunnen de samenstelling van de functie bekijken door de naam te typen of functions :

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

We hebben ook toegang tot elke functie door zijn positie in de volgorde:

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

Over het algemeen kan deze benadering nuttig zijn wanneer duidelijkheid belangrijker is dan snelheid.

Opdracht met% <>%

Het magrittr pakket bevat een samengestelde toewijzingsinfix-operator, %<>% , die een waarde bijwerkt door deze eerst in een of meer rhs expressies te rhs en vervolgens het resultaat toe te wijzen. Dit elimineert de noodzaak om tweemaal een objectnaam te typen (eenmaal aan elke zijde van de toewijzingsoperator <- ). %<>% moet de eerste infix-operator in een keten zijn:

library(magrittr)
library(dplyr)

df <- mtcars

In plaats van te schrijven

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

of

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

De samengestelde toewijzingsoperator zal zowel df pijpen als opnieuw toewijzen:

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

Inhoud wordt weergegeven met% $%

De operator voor de expositiepijp, %$% , stelt de kolomnamen als R-symbolen in het linkerobject aan de rechterexpressie bloot. Deze operator is handig wanneer u functies inschakelt die geen data (in tegenstelling tot bijvoorbeeld lm ) en die geen data.frame en kolomnamen als argumenten gebruiken (de meeste van de belangrijkste dplyr-functies).

Met de expositiepijpexploitant %$% kan een gebruiker voorkomen dat een pijplijn wordt verbroken wanneer naar kolomnamen moet worden verwezen. Stel bijvoorbeeld dat u een data.frame wilt filteren en vervolgens een correlatietest op twee kolommen met 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 geeft de standaard %>% pipe het data.frame door aan filter() , terwijl de %$% pipe de kolomnamen blootstelt aan cor.test() .

De expositiepijp werkt als een pijpversie van de basis R with() functies, en dezelfde objecten aan de linkerkant worden geaccepteerd als invoer.

Gebruik van de pijp met dplyr en ggplot2

De operator %>% kan ook worden gebruikt om de uitvoer van dplyr naar ggplot te leiden. Dit creëert een uniforme exploratory data analysis (EDA) -pijplijn die gemakkelijk kan worden aangepast. Deze methode is sneller dan de aggregaties intern uitvoeren in ggplot en heeft het extra voordeel dat onnodige tussenliggende variabelen worden vermeden.

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

Bijwerkingen creëren met% T>%

Sommige functies in R produceren een bijwerking (bijv. Opslaan, afdrukken, plotten, enz.) En retourneren niet altijd een betekenisvolle of gewenste waarde.

%T>% (tee-operator) stelt u in staat om een waarde door te sturen naar een bijwerking-producerende functie terwijl de oorspronkelijke lhs waarde intact blijft. Met andere woorden: de tee-operator werkt als %>% , behalve dat de retourwaarden lhs zelf zijn en niet het resultaat van de rhs functie / uitdrukking.

Voorbeeld: maak, pijp, schrijf en retourneer een object. Als %>% in dit voorbeeld in plaats van %T>% zou worden gebruikt, zou de variabele all_letters NULL bevatten in plaats van de waarde van het gesorteerde object.

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

Waarschuwing: als u een object zonder naam naar save() stuurt, krijgt u een object met de naam . wanneer geladen in de werkruimte met load() . Er is echter een oplossing mogelijk met behulp van een helperfunctie (die ook inline kan worden geschreven als een anonieme functie).

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow