R Language
Операторы труб (%>% и другие)
Поиск…
Вступление
Операторы труб, доступные в 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")