R Language
파이프 운영자 (%> % 및 기타)
수색…
소개
magrittr
, dplyr
및 기타 R 패키지에서 사용할 수있는 파이프 연산자는보다 일반적인 R 중첩 방식 대신 중위 연산자를 사용하여 다음 단계의 입력으로 한 단계의 결과를 전달하여 일련의 작업을 사용하여 데이터 객체를 처리합니다 함수 호출.
파이프 연산자의 의도 된 목적은 작성된 코드의 사람의 가독성을 높이는 데 있습니다. 성능 고려 사항은주의 절을 참조하십시오.
통사론
lhs %> % rhs #
rhs(lhs)
대한 파이프 구문rhs(lhs, a = 1)
대한 lhs %> % rhs (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의 의미를 사용하는 함수 호출 |
비고
%>%
를 사용하는 패키지
파이프 연산자는 magrittr
패키지에 정의되어 있지만 dplyr
패키지 ( dplyr
에서 정의를 magrittr
)를 통해 큰 가시성과 인기를 얻었습니다. 이제는 공통적 인 데이터 표현과 API 디자인을 공유하기 때문에 "조화롭게 작동 하는 " 패키지 컬렉션 인 tidyverse
일부입니다.
magrittr
패키지는 복합 할당 파이프 %<>%
, 박람회 파이프 %$%
및 T 형 연산자 %T>%
와 같이 배관 유연성을 원하는 사용자를 위해 파이프 연산자의 여러 변형을 제공합니다. 또한 특수한 구문 ( +
, [
, [[
, etc.])을 가진 공통 함수를 대체하여 파이프 체인 내에서 쉽게 사용할 수 있도록 별명 기능 세트를 제공합니다.
문서 찾기
어떤 중위 연산자 ( +
, *
, ^
, &
, %in%
)와 마찬가지로 공식 문서는 ?'%>%'
또는 help('%>%')
와 같이 따옴표로 묶어서 찾을 수 있습니다 pkg:magrittr
을 첨부하는 패키지를로드했다고 가정).
단축키
RStudio 에는 파이프 연산자로 Ctrl+Shift+M
( Windows 및 Linux ), Cmd+Shift+M
( Mac )과 같은 Cmd+Shift+M
있습니다.
성능 고려 사항
파이프 연산자는 유용하지만, 주로 파이프 오 퍼 레이션을 사용하는 오버 헤드로 인해 성능에 부정적인 영향이 있음을 유의하십시오. 파이프 연산자를 사용할 때는 다음 두 가지 사항을 신중하게 고려하십시오.
- 기계 성능 (루프)
- 평가 (
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 (Right Hand Side)의 첫 번째 인수로 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
사용하여 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
표현식에 파이핑하여 값을 업데이트 한 다음 결과를 할당하여 값을 업데이트하는 복합 할당 infix-operator %<>%
되어 있습니다. 이렇게하면 오브젝트 이름을 두 번 입력 할 필요가 없습니다 (할당 연산자 <-
양측에 한 번씩). %<>%
는 체인의 첫 번째 중온 연산자 여야합니다.
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 함수).
박람회 파이프 연산자 %$%
사용하면 열 이름을 참조해야 할 때 파이프 라인이 끊어지는 것을 방지 할 수 있습니다. 예를 들어 cor.test
을 필터링 한 다음 cor.test
하여 두 열에 대해 상관 관계 테스트를 실행한다고 가정 해 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()
로 노출합니다.
박람회 파이프는 base 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
이 포함 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()
를 사용하여 작업 공간에 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")