有没有一种方法可以在base R中使用管道,而不必定义自己的函数(即“开箱即用”的东西),也不必加载任何外部包?也就是说,一些(基R)替代magrittr管道%>%。这个功能在R 4.0.3中可用吗?如果没有,在哪个R版本中可以找到,如果有,是如何实现的?
%>%
lztngnrs1#
在R中,|>用作管道操作符。(从4.1.0开始)左侧表达式 lhs 作为第一个自由参数插入到右侧表达式 rhs 的调用中。
|>
mtcars |> head() # same as head(mtcars) # mpg cyl disp hp drat wt qsec vs am gear carb #Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 #Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 #Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 #Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 #Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 #Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 mtcars |> head(2) # same as head(mtcars, 2) # mpg cyl disp hp drat wt qsec vs am gear carb #Mazda RX4 21 6 160 110 3.9 2.620 16.46 0 1 4 4 #Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
也可以在 rhs 调用中使用命名参数和占位符_来指定 lhs 的插入位置。占位符只能在 rhs 上出现一次。(自4.2.0起)
_
mtcars |> lm(mpg ~ disp, data = _) #mtcars |> lm(mpg ~ disp, _) #Error: pipe placeholder can only be used as a named argument #Call: #lm(formula = mpg ~ disp, data = mtcars) # #Coefficients: #(Intercept) disp # 29.59985 -0.04122
或者在“one”之前显式地命名参数:
mtcars |> lm(formula = mpg ~ disp)
如果占位符被多次使用,或者在任何位置上用作命名或未命名的参数,或者用于禁用的函数:使用(匿名)函数。
mtcars |> (\(.) .[.$cyl == 6,])() #mtcars ->.; .[.$cyl == 6,] # Alternative using bizarro pipe #local(mtcars ->.; .[.$cyl == 6,]) # Without overwriting and keeping . # mpg cyl disp hp drat wt qsec vs am gear carb #Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 #Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 #Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6 mtcars |> (\(.) lm(mpg ~ disp, .))() #Call: #lm(formula = mpg ~ disp, data = .) # #Coefficients: #(Intercept) disp # 29.59985 -0.04122 1:3 |> setNames(object = _, nm = _) #Error in setNames(object = "_", nm = "_") : # pipe placeholder may only appear once 1:3 |> (\(.) setNames(., .))() #1 2 3 #1 2 3 1:3 |> list() |> setNames(".") |> with(setNames(., .)) #1 2 3 #1 2 3 #The same but over a function ._ <- \(data, expr, ...) { eval(substitute(expr), list(. = data), enclos = parent.frame()) } 1:3 |> ._(setNames(., .)) #1 2 3 #1 2 3
某些功能已禁用。
1:3 |> `+`(4) #Error: function '+' not supported in RHS call of a pipe
但是有些仍然可以通过将它们放置在brake中来调用,通过函数::调用它们,在函数中调用它或定义函数的链接。
::
1:3 |> (`+`)(4) #[1] 5 6 7 1:3 |> base::`+`(4) #[1] 5 6 7 1:3 |> (\(.) . + 4)() #[1] 5 6 7 fun <- `+` 1:3 |> fun(4) #[1] 5 6 7
一个写为x |> f(y)的表达式被解析为f(x, y)。当管道中的代码被顺序写入时,用于求值的常规R语义适用。因此管道表达式仅在 rhs 表达式中首次使用时才会被求值。
x |> f(y)
f(x, y)
-1 |> sqrt() |> (\(x) 0)() #[1] 0 . <- -1 . <- sqrt(.) #Warning message: #In sqrt(.) : NaNs produced (\(x) 0)(.) #[1] 0 x <- data.frame(a=0) f1 <- \(x) {message("IN 1"); x$b <- 1; message("OUT 1"); x} f2 <- \(x) {message("IN 2"); x$c <- 2; message("OUT 2"); x} x|> f1() |> f2() #IN 2 #IN 1 #OUT 1 #OUT 2 # a b c #1 0 1 2 f2(f1(x)) #IN 2 #IN 1 #OUT 1 #OUT 2 # a b c #1 0 1 2 . <- x . <- f1(.) #IN 1 #OUT 1 f2(.) #IN 2 #OUT 2 # a b c #1 0 1 2
dced5bon2#
你可以使用bizarro pipe(也叫this),它巧妙地使用了现有的语法,不需要函数或包。
mtcars ->.; transform(., mpg = 2 * mpg) ->.; # change units lm(mpg ~., .) ->.; coef(.)
其中->.;看起来像一个管道。
->.;
b4qexyjb3#
在撰写本文时,R的发布版本(4.0.3)不包含管道操作符。但是,正如在useR! 2020 keynote中所指出的,基础|>运算符正在开发中。来自2020-12-15 R-devel daily source的pipeOp手册页:管道表达式将lhs表达式的结果通过管道传递到rhs表达式。如果rhs表达式是一个调用,那么lhs将作为调用中的第一个参数插入。因此x |> f(y)将被解释为f(x, y)。为了避免歧义,rhs调用中的函数在语法上可能不是特殊的,例如+或if。如果rhs表达式是一个function表达式,则调用函数时将lhs值作为其参数。当lhs需要作为rhs调用中的第一个参数以外的参数传递时,这很有用。该操作符何时会进入发布版本,或者在发布之前是否会更改,目前尚不清楚。
pipeOp
lhs
rhs
+
if
function
3条答案
按热度按时间lztngnrs1#
在R中,
|>
用作管道操作符。(从4.1.0开始)左侧表达式 lhs 作为第一个自由参数插入到右侧表达式 rhs 的调用中。
也可以在 rhs 调用中使用命名参数和占位符
_
来指定 lhs 的插入位置。占位符只能在 rhs 上出现一次。(自4.2.0起)或者在“one”之前显式地命名参数:
如果占位符被多次使用,或者在任何位置上用作命名或未命名的参数,或者用于禁用的函数:使用(匿名)函数。
某些功能已禁用。
但是有些仍然可以通过将它们放置在brake中来调用,通过函数
::
调用它们,在函数中调用它或定义函数的链接。一个写为
x |> f(y)
的表达式被解析为f(x, y)
。当管道中的代码被顺序写入时,用于求值的常规R语义适用。因此管道表达式仅在 rhs 表达式中首次使用时才会被求值。dced5bon2#
你可以使用bizarro pipe(也叫this),它巧妙地使用了现有的语法,不需要函数或包。
其中
->.;
看起来像一个管道。b4qexyjb3#
在撰写本文时,R的发布版本(4.0.3)不包含管道操作符。
但是,正如在useR! 2020 keynote中所指出的,基础
|>
运算符正在开发中。来自2020-12-15 R-devel daily source的
pipeOp
手册页:管道表达式将
lhs
表达式的结果通过管道传递到rhs
表达式。如果
rhs
表达式是一个调用,那么lhs
将作为调用中的第一个参数插入。因此x |> f(y)
将被解释为f(x, y)
。为了避免歧义,rhs
调用中的函数在语法上可能不是特殊的,例如+
或if
。如果
rhs
表达式是一个function
表达式,则调用函数时将lhs
值作为其参数。当lhs
需要作为rhs
调用中的第一个参数以外的参数传递时,这很有用。该操作符何时会进入发布版本,或者在发布之前是否会更改,目前尚不清楚。