yihui yihui ,你好
看到这个更新,确实觉得不错。
但在官网也没说明。新的管道操作有没有快捷键啊。是不是和{magrittr}
一样的?
我认为管道操作一定要有快捷键,这样写起代码来才顺畅
R 4.1.0 官方支持管道 |>,爷青结
lianghao118 RStudio 吗? Tools -> Global Options -> Code -> Use native pipe operator
- 已编辑
x <- c(1:10, NA)
a_fun <- function(x) {
. <- x
. <- ifelse(is.na(.), 0, .)
. <- (. + 1) * 3
. <- sort(.)
head(., 5)
}
b_fun <- function(x) {
x |>
{\(.) ifelse(is.na(.), 0, .)}() |>
{\(.) (. + 1) * 3}() |>
sort() |>
head(5)
}
a_fun(x)
#> [1] 3 6 9 12 15
b_fun(x)
#> [1] 3 6 9 12 15
dput(a_fun)
#> function (x)
#> {
#> . <- x
#> . <- ifelse(is.na(.), 0, .)
#> . <- (. + 1) * 3
#> . <- sort(.)
#> head(., 5)
#> }
dput(b_fun)
#> function (x)
#> {
#> head(sort({
#> function(.) (. + 1) * 3
#> }({
#> function(.) ifelse(is.na(.), 0, .)
#> }(x))), 5)
#> }
<sup>Created on 2021-05-24 by the reprex package (v2.0.0)</sup>
想了好久,感觉我还是更喜欢传统的写法。也可以在Rstudio设置 ". <- " 快捷键。写出来的代码也可以很简练。如函数a_fun。这本身就符合奥卡姆剃刀原则。这是其一。
其二, 使用管道符号以后,写出来函数的格式不稳定。比如,dput(b_fun) 以后和原来的代码完全不一样。虽然这对大部分用户来说并不是什么问题,但我本人不太喜欢。
个人观点。
wangbinzjcc 这个匿名函数写法简直是天书,有种看 perl 代码的赶脚
JackieMe 你不是第一个这么说的人。一堆特殊字符(大括号、反斜杠、小括号、点、竖线、小于号)堆在一起,确实是太 Perl 了。
所以我还是喜欢 a_fun
里的写法,一步一赋值,简单明了,排错方便。管道的写法太怂恿用户追求形式上的美感,而这种外表美掩盖了潜在的代价。每次看到这种讨论,总让我联想起古诗与现代诗。形式美是一种美,但特别容易病态和狂热,舍本逐末(比如我认为诗的平仄差不多就行,完全不必成为规则;管道也不必管天管地,不是所有代码都适合管道;管道本是 Unix 的发明,也没见到 Shell 脚本到处都是管道吧,通常也都是普通的 if
判断或 for
循环;我一直都不是很理解为啥 R 社区这么狂热于管道)。
但 a_fun
这种一步一赋值的写法最容易被人诟病的是,当变量名比较长时,写起来就很啰嗦了。这里用 .
简写看起来还行。我通常绕过这个问题的办法是写新函数:如果需要重复操作一个变量,那么就把这部分代码抽出去写一个新函数,新函数的参数用短变量名。如:
c_fun <- function(x) {
x_squared <- x^2
x <- (x_squared + 1) * (x_squared -2)
head(x, 5)
}
为了避免重复敲 x_squared
这个长名字,可以新写一个函数,参数用短名:
d_fun <- function(x) {
(x + 1) * (x -2)
}
然后调用新函数:
c_fun <- function(x) {
x <- d_fun(x^2)
head(x, 5)
}
抽离局部代码到新函数这种做法也便于单元测试。不过我这都是从开发者角度说的。数据分析的代码风格会不一样,可能不会频繁抽离新函数。
- 已编辑
我自己刚开始接触管道的时候, 有过什么都想上管道的倾向 ... 现在处于一种混杂的状态. 至于什么时候用什么时候不用, 我的标准是认知上的流畅和简洁. 但这个 "简洁" 并不是完全说输入的代码越少越好. 我下面举一些例子:
my_data[, c("var_1", "var_2", "var_3")] %>% my_fun()
上面这个例子我觉得就是一个简单的, 但是显示管道优点的例子. 因为它的形式是贴合你的思维过程的. 如果你用传统的方式来写, 就会有点拗口:
my_fun(my_data[, c("var_1", "var_2", "var_3")])
因为 my_fun()
这个操作是后发生的.
如果用中间的变量, 我个人会觉得有点笨拙:
new_data <- my_data[, c("var_1", "var_2", "var_3")]
my_fun(new_data)
这么写对我个人来说还有三个不爽的点:
new_data
这个变量是不重复使用的, 有点废话.new_data
会阻断思维过程, 本来一句话能说清楚的, 变得冗长了. 我下次看的时候, 加工时间会更长.- 如果你采用中间变量是为了更清晰, 更显性, 那么这背后需要你花心思去取直观简洁的变量名, 这个过程对我来说很痛苦.
但就算我支持管道, 我也不会刻意这样写:
c("var_1", "var_2", "var_3") %>%
{my_data[, .]} %>%
my_fun()
因为我思考的时候, my_data[, c("var_1", "var_2", "var_3")]
是整体出现的. 字面上的, 刻意的简洁反而是损害思维上的简洁的. 除非 c("var_1", "var_2", "var_3")]
是我之前处理的结果.
这些例子看起来很无足轻重, 但是是我实际开发时的体验的缩影.
- 已编辑
开辟第三战场
# Example - 1
1:10 ->.; head(.) # 如果换行分号就可去掉了。
# Example - 2
1:10 ->.
head(.)
# Example - 3
library(dplyr)
mtcars ->.
group_by(., cyl) ->.
summarise(., mpg_avg = mean(mpg)) -> df
- 已编辑
chuxinyuan
可以设置个 " ->.; "的快捷键。 想换行就换行,不想换行就接着写。哈哈~~
10:1 |> sort() |> head(5) ->.; ifelse(. < 5, 0, .) ->.; plot(.)
这样是不是有点梦幻了。
等同于这样:
. <- head(sort(10:1), 5)
. <- ifelse(. < 5, 0, .)
plot(.)
wangbinzjcc 有分号普适性好点,就是太丑。纯娱乐,呵呵
- 已编辑
设置了还是... @@“
x 3.3 GiB [master*]> devtools::session_info()$platform |>
unlist() |>
data.frame(Category = names(.), session_info = .)
Error in data.frame(unlist(devtools::session_info()$platform), Category = names(.), :
arguments imply differing number of rows: 9, 0
x 3.3 GiB [master*]> devtools::session_info()$platform %>%
unlist() %>%
data.frame(Category = names(.), session_info = .)
Category session_info
version version R version 4.1.0 (2021-05-18)
os os Ubuntu 20.04.2 LTS
system system x86_64, linux-gnu
ui ui RStudio
language language en
collate collate en_US.UTF-8
ctype ctype en_US.UTF-8
tz tz Asia/Tokyo
date date 2021-05-30
好了~
3.3 GiB [master*]> devtools::session_info()$platform %>%
unlist() %>%
(function(df) data.frame(Category = names(df), session_info = df))()
Category session_info
version version R version 4.1.0 (2021-05-18)
os os Ubuntu 20.04.2 LTS
system system x86_64, linux-gnu
ui ui RStudio
language language en
collate collate en_US.UTF-8
ctype ctype en_US.UTF-8
tz tz Asia/Tokyo
date date 2021-05-30
yihui OK.6月9号,发布了正式版1.4.1717。看到官方更新说明了!
https://blog.rstudio.com/2021/06/09/rstudio-v1-4-update-whats-new/
最新4.2.0
版的 R 支持用 _
作为原生管道 |>
的占位符了