管道纯粹在基础R(“基础管道”)中?
有没有办法在基本 R 中进行管道传输,而无需定义自己的函数(即“开箱即用”的东西),也无需加载任何外部包?
也就是说,一些(基数 R)替代 magrittr pipe %>%。可能在即将推出的 R (?)
此功能在 R 4.0.3 中是否可用。如果不是,它是在哪个 R 版本中找到的,如果是,这是如何实现的?
回答
您可以使用bizarro 管道(也是this),它巧妙地使用了现有语法,不需要函数或包。例如
mtcars ->.;
transform(., mpg = 2 * mpg) ->.; # change units
lm(mpg ~., .) ->.;
coef(.)
这里->.;看起来像一个管道。
回答
在撰写此答案时,R (4.0.3) 的发行版不包含管道运算符。
但是,正如在userR中指出的那样!2020年主题演讲,基地|>运营商正在开发中。
来自2020-12-15pipeOp的 R-devel每日源的手册页:
管道表达式将表达式的结果传递或管道
lhs
到rhs表达式。
如果
rhs表达式是一个调用,则lhs将作为调用中的第一个参数插入。所以x |> f(y)被解释为f(x, y)。为避免歧义,rhs调用中的函数在
语法上可能并不特殊,例如+或
if。
如果该
rhs表达式是一个function表达式,则该函数以该lhs值作为其参数被调用。这在lhs需要作为rhs调用中第一个以外的参数传递时很有用。
该运营商何时将其纳入发布版本,或者是否可能在发布之前发生变化,尚不得而知。
回答
从 R-Version 4.1.0 开始,管道|>处于稳定版本。
手册中的一些示例:
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
将 lhs 传递给第一个参数以外的参数:
mtcars |> subset(cyl == 4) |> (function(d) lm(mpg ~ disp, data = d))()
#mtcars |> subset(cyl == 4) |> ((d) lm(mpg ~ disp, data = d))() #Alternative using () instead of function() as mentioned in the comments by @waldi
#mtcars |> subset(cyl == 4) ->.; lm(mpg ~ disp, data = .) #Alternative using bizarro pipe as already mentioned here by @g-grothendieck
#local({mtcars |> subset(cyl == 4) ->.; lm(mpg ~ disp, data = .)}) #Does not overwrite and keep .
#mtcars |> subset(cyl == 4) |> lm(formula = mpg ~ disp) #Alternative fills up all arguments before (taken from comment of @g-grothendieck)
#Call:
#lm(formula = mpg ~ disp, data = d)
#
#Coefficients:
#(Intercept) disp
# 40.8720 -0.1351
另一种选择是使用当前需要激活的PIPEBIND:
Sys.setenv(`_R_USE_PIPEBIND_` = TRUE)
mtcars |> subset(cyl == 4) |> . => lm(mpg ~ disp, data = .)
- Looking forward to trying! Any noticeable differences from the magrittr pipe? Does it use `.` to represent the placeholder for the passed through argument?