当前位置:网站首页>R语言管道符(%>%)及占位(.)的简单介绍
R语言管道符(%>%)及占位(.)的简单介绍
2022-07-27 10:02:00 【万木春*】
前言
刚开始学习R语言的时候,经常模仿别人的代码,囫囵吞枣。如今,自己研究的领域中,经常使用的操作也相对熟练,所以,需要静心补一补脑子里的洞,简单整理一下R语言 Magrittr 相关的管道操作。在代码整洁和可维护性方面,Magrittr 管道符(%>%)作用显著
一个简单的例子
刚开始使用R的时候,我为了减少赋值的频次,就把好多个函数套一起使用,经常少了某个括号,看起来也有些”奇怪“,或者说复杂、难理解…比如:
round(cos(exp(sin(log10(sqrt(25))))), 2)
# -0.33
后来,偶然看见师兄的代码,发现了这个符号%>%,才认识了管道符(开始用bash管道符的时候,想过为啥R没有,后来才知道是我太菜…),有了管道符之后就有了下面这样的操作:
library(magrittr)
sqrt(25) %>%
log10() %>%
sin() %>%
exp() %>%
cos() %>%
round(2)
# -0.33
这样看起来,是不是更好理解、更整洁?那么,管道符做了什么,比如%>%,它把前边的输出结果,呈递给下一个函数,作为输入,例子中就是把sqrt(25)的结果递给log10(),类推。所以,管道符做的,就是把其左边的结果递给右边,作为输入。这会使代码更加的整洁、可读,并且维护性也会提高。
管道符及占位、花括号 {} 、美元符号$
占位
很多时候,我们使用的函数,数据输入的位置并不是第一个参数,或者,我想要放到我想放的位置,比如gsub等,这类函数在管道符右边的时候,就需要一个东西,指定前面(管道符左边)的输出该放在后面函数的哪个位置。这个东西就是:.。没错,就是这个句点,这样用:
argument2 %>% function(argument1, .)argument1 %>% function(argument2)
例子:
1:5 %>%
paste(., letters[.])
# [1] "1 a" "2 b" "3 c" "4 d" "5 e"
# install.packages("gapminder")
library(gapminder)
gapminder %>%
dplyr::pull(continent) %>%
gsub("Europe", "EUROPE", .) %>%
head(20)
# [1] "Asia" "Asia" "Asia" "Asia" "Asia" "Asia" "Asia" "Asia"
# [9] "Asia" "Asia" "Asia" "Asia" "EUROPE" "EUROPE" "EUROPE" "EUROPE"
# [17] "EUROPE" "EUROPE" "EUROPE" "EUROPE"
先上一段代码:
gapminder %>%
dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>% round(2) %>%
head(10)
# [1] 779.45 820.85 853.10 836.20 739.98 786.11 978.01 852.40 649.34 635.34
针对数据的continent 列,筛选出包含Asia的数据,然后拿出gdpPercap列,保留两位小数,然后取前十个。很简单的一段代码,但是如果为了缩短函数,像下面这样,把简单的函数head()和round()嵌套在一起,得到了不一样的结果:
gapminder %>%dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>%
head(round(2), 10)
# [1] 779.4453 820.8530
gapminder %>%
dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>%
head(., round(2), 10)
# [1] 779.4453 820.8530
看了head(., round(2), 10),应该就会明白上边代码的输出。首先,从管道符左边过来的数据,并没有直接作为round函数的输入,而是给了head函数。第二点,round函数有两个参数,第一个位输入的vector,第二位是整数,用来指定保留的数位,默认是0,round(2) 返回的结果是2。head函数只接受两个参数,第一位是输入,第二位是指定打印多少,它接收了从管道左边传来的数据,作为第一个参数,round(2)的输出成了它的第二位参数,后面那个10就没用了……所以,一串代码只返回了两个数字,而不是我们想要的效果。想要嵌套一下,可以这样:
gapminder %>%
dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>%
head(round(., 2), 10)
# [1] 779.45 820.85 853.10 836.20 739.98 786.11 978.01 852.40 649.34 635.34
在使用管道符的时候,需要特别注意数据输入的位置,合适正确的使用.占位
all_equal(
gapminder %>%
dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>%
round(2) %>%
head(10),
gapminder %>%
dplyr::filter(continent == "Asia") %>%
dplyr::pull(gdpPercap) %>%
{
head(round(., 2), 10)}
)
[1] TRUE
花括号 {}
不多说,直接上代码:
gapminder %>%
dplyr::filter(continent == "Asia") %>%
stats::cor(.$lifeExp, .$gdpPercap)
gapminder %>%
dplyr::filter(continent == "Asia") %>%
stats::cor(lifeExp, gdpPercap)
报错:
Error in if (is.na(na.method)) stop(“invalid ‘use’ argument”) : the condition has length > 1
Error in pmatch(use, c(“all.obs”, “complete.obs”, “pairwise.complete.obs”, : object ‘gdpPercap’ not found
加上花括号:
gapminder %>%
dplyr::filter(continent == "Asia") %>%
{
stats::cor(.$lifeExp, .$gdpPercap)}
# Equivalent to the code above
gapminder %>%
dplyr::filter(continent == "Asia") -> only_asia
stats::cor(only_asia$lifeExp, only_asia$gdpPercap)
不报错。相对比较容易理解,stats::cor接受两个参数,我们想要的是.$lifeExp, .$gdpPercap,但是管道左边来的数据占了一个位置,并且还是个data.frame,自然就报错了,加上花括号 {},告诉管道符,我不想按照默认的,把左边的输出给右边,这样,stats::cor就只接受.$lifeExp, .$gdpPercap,正常运行。
美元符号 $
两段代码:
library(dplyr)
gapminder %>%
dplyr::group_by(continent, year) %>%
dplyr::summarise(count = n()) %>%
dplyr::mutate(total = sum(count),
prop = count / total) %>%
head()
# continent year count total prop
# Africa 1952 52 624 0.08333333
# Africa 1957 52 624 0.08333333
# Africa 1962 52 624 0.08333333
# Africa 1967 52 624 0.08333333
# Africa 1972 52 624 0.08333333
# Africa 1977 52 624 0.08333333
gapminder %>%
dplyr::group_by(continent, year) %>%
dplyr::summarise(count = n()) %>%
dplyr::mutate(total = sum(.$count),
prop = count / total) %>%
head()
# continent year count total prop
# Africa 1952 52 1704 0.03051643
# Africa 1957 52 1704 0.03051643
# Africa 1962 52 1704 0.03051643
# Africa 1967 52 1704 0.03051643
# Africa 1972 52 1704 0.03051643
# Africa 1977 52 1704 0.03051643
第一段代码的输出并不是我想要的结果,第二段代码才是。.$允许我使用初始的数据也就是gapminder来计数,而不是dplyr::group_by分组之后的分组数据。所以,在使用dplyr::group_by之后,要注意我们的目的是什么,合理地使用.$,得到期望的结果。
其他管道符 %<>%、%T>%、%$%
对于其他的管道符,这里就举几个例子,不再一一展开讨论了
%<>%
mtcars <- mtcars %>%
transform(cyl = cyl * 2)
mtcars %<>% transform(cyl = cyl * 2)
对数据集mtcars操作,输出又赋给了变量mtcars
%T>%
rnorm(200) %>%
matrix(ncol = 2) %T>%
plot %>% # plot usually does not return anything.
colSums
# [1] -4.018676 -27.018219
分支操作,随机生成200个数组成两列的矩阵之后,数据分别流向了两个方向,一是画个图,二是算一下列的和
%$%
iris %>%
subset(Sepal.Length > mean(Sepal.Length)) %$%
cor(Sepal.Length, Sepal.Width)
mtcars %$%
cor(disp, mpg)
这个看起来和上边的花括号{}类似,但是并不一样,它把前面的数据暴露出来,可以任意使用数据中变量,而不需要.$获取。
总结
在使用管道操作的时候,要理解管道的输出形式,正确的使用占位等……不罗嗦了,慢慢探索吧

参考
https://magrittr.tidyverse.org/
边栏推荐
- Robotframework+eclispe environment installation
- Excellent Kalman filter detailed article
- Overview of PCL modules (1.6)
- Matlab-绘制叠加阶梯图和线图
- pillow的原因ImportError: cannot import name ‘PILLOW_VERSION‘ from ‘PIL‘,如何安装pillow<7.0.0
- Hugo learning notes
- Shell变量、系统预定义变量$HOME、$PWD、$SHELL、$USER、自定义变量、特殊变量$n、$#、$*、[email protected]、$?、env看所有的全局变量值、set看所有变量
- Based on LSM tree idea Net 6.0 C # write a kV database (case version)
- SE(Squeeze and Excitation)模块的理解以及代码实现
- Data visualization
猜你喜欢

Huawei switch dual uplink networking smart Link Configuration Guide

pytorch的安装(非常详细)

Mysql database experiment training 5, data query YGGL database query (detailed)

Dcgan paper improvements + simplified code

3D face reconstruction and dense alignment with position map progression network

Anchor Free检测器:CenterNet

WGAN、WGAN-GP、BigGAN

使用 LSM-Tree 思想基于.NET 6.0 C# 写个 KV 数据库(案例版)

PCL各模块概述(1.6)
![Shell函数、系统函数、basename [string / pathname] [suffix] 可以理解为取路径里的文件名称 、dirname 文件绝对路径、自定义函数](/img/3d/d7276d2010f1d77a3bd572cc66eced.png)
Shell函数、系统函数、basename [string / pathname] [suffix] 可以理解为取路径里的文件名称 、dirname 文件绝对路径、自定义函数
随机推荐
卸载CUDA11.1
Different binary conversion of MATLAB
Matlab- draw bifurcation and chaotic bifurcation diagrams
Metaaploit-后渗透技知识
Matlab-绘制叠加阶梯图和线图
Matlab sound classification based on short-time neural network
Cannot start after installing MySQL 5.7.27 in CentOS 7? (Language bash)
Switch port mirroring Configuration Guide
NFS 服务器的搭建
Matlab- draw date and duration diagram
Robotframework+eclispe environment installation
Food safety | is sugar free really sugar free? These truths need to be known
Local connection to remote server database under Windows platform (I)
【英雄哥六月集训】第 28天: 动态规划
Shell的read 读取控制台输入、read的使用
声音处理之-梅尔频率倒谱系数(MFCC)
Shell integrated application cases, archiving files, sending messages
Understanding and code implementation of Se (sequence and exception) module
Excellent Kalman filter detailed article
Learn typescript (1)