Поиск…


Вступление

Операторы труб, доступные в magrittr , dplyr и других R-пакетах, обрабатывают объект данных, используя последовательность операций, передавая результат одного шага в качестве ввода для следующего шага с использованием инфикс-операторов, а не более типичный R-метод вложенных вызовы функций.

Обратите внимание, что целью операторов труб является повышение удобочитаемости письменного кода. См. Раздел «Примечания» для соображений производительности.

Синтаксис

  • lhs%>% rhs # pipe синтаксис для rhs(lhs)

  • lhs%>% rhs (a = 1) # синтаксис канала для rhs(lhs, a = 1)

  • lhs%>% rhs (a = 1, b =.) # синтаксис канала для rhs(a = 1, b = lhs)

  • lhs% <>% rhs # pipe синтаксис для lhs <- rhs(lhs)

  • lhs% $% rhs (a) # синтаксис канала для with(lhs, rhs(lhs$a))

  • lhs% T>% rhs # синтаксис канала для { rhs(lhs); lhs }

параметры

л.ш. шк
Значение или заполнитель magrittr. Вызов функции с использованием семантики magrittr

замечания

Пакеты, которые используют %>%

Оператор трубы определен в пакете magrittr , но он приобрел огромную видимость и популярность в пакете dplyr (который импортирует определение из magrittr ). Теперь это часть tidyverse , которая представляет собой набор пакетов, которые «работают в гармонии, потому что они имеют общие представления данных и дизайн API» .

Пакет magrittr также предоставляет несколько вариантов оператора труб для тех, кто хочет больше гибкости в трубопроводах, например, составной соединительный трубопровод %<>% , трубопровод экспозиции %$% и оператор тройника %T>% . Он также предоставляет набор функций псевдонимов для замены общих функций, которые имеют специальный синтаксис ( + , [ , [[ и т. Д.]), Чтобы их можно было легко использовать в цепочке труб.

Поиск документации

Как и в любом инфиксном операторе (например, + , * , ^ , & , %in% ), вы можете найти официальную документацию, если вы поместите ее в кавычки: ?'%>%' Или help('%>%') ( если вы загрузили пакет, который прикрепляет pkg:magrittr ).

Клавиатурный

В RStudio для оператора трубы есть специальная горячая клавиша: Ctrl+Shift+M ( Windows и Linux ), Cmd+Shift+M ( Mac ).

Рекомендации по производительности

В то время как оператор трубы полезен, имейте в виду, что это негативно сказывается на производительности, в основном из-за накладных расходов на его использование. При использовании оператора трубы внимательно рассмотрите следующие две вещи:

  • Производительность станка (петли)
  • Оценка ( 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

Если мы не хотим, чтобы LHS (Left Hand Side) использовался в качестве первого аргумента в RHS (Right Hand Side), есть временные решения, такие как именование аргументов или использование . для указания того, куда поступает входной канал.

# 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 содержит инфикс-оператор составного назначения, %<>% , который обновляет значение, сначала передавая его в одно или несколько выражений rhs а затем назначая результат. Это устраняет необходимость дважды вводить имя объекта (один раз с каждой стороны оператора присваивания <- ). %<>% должен быть первым инфикс-оператором в цепочке:

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 и столбцов в качестве аргументов (большинство основных функций dplyr).

Оператор трубы изложения %$% позволяет пользователю избежать разрыва конвейера при необходимости ссылаться на имена столбцов. Например, предположим, что вы хотите отфильтровать файл data.frame, а затем запустить корреляционный тест на двух столбцах с 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

Здесь стандартный %>% pipe передает файл data.frame через filter() , в то время как %$% pipe предоставляет имена столбцов 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>% (тройник оператор) позволяет пересылать значение в побочном эффекте продуцирующих функцию, сохраняя при этом оригинальном lhs значения нетронутым. Другими словами: оператор tee работает как %>% , за исключением того, что возвращаемые значения являются lhs , а не результатом функции / выражения rhs .

Пример. Создайте, создайте канал, напишите и верните объект. Если %>% были использованы вместо %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