R语言中的管道操作

2023-11-01

前言

使用R语言进行数据处理是非常方便的,几行代码就可以完成很复杂的操作。但是,对于数据的连续处理,还是有人觉得代码不好看,要么是长长的函数嵌套调用,有点像Lisp感觉,括号包一切;要么就是每次操作赋值一个临时变量,啰嗦。为什么就不能像Linux的管道一样优雅呢?

magrittr包在这样场景中被开发出来,通过管道的方式让连续复杂数据的处理操作,代码更短,更容易读,甚至一行代码可以搞定原来10行代码的事情。

目录

  1. magrittr介绍
  2. magrittr安装
  3. magrittr包的基本使用
  4. magrittr包的扩展功能

1. magrittr介绍

magrittr包被定义为一个高效的管道操作工具包,通过管道的连接方式,让数据或表达式的传递更高效,使用操作符%>%,可以直接把数据传递给下一个函数调用或表达式。magrittr包的主要目标有2个,第一是减少代码开发时间,提高代码的可读性和维护性;第二是让你的代码更短,再短,短短短…

magrittr包,主要定义了4个管道操作符,分另是%>%, %T>%, %$% 和 %<>%。其中,操作符%>%是最常用的,其他3个操作符,与%>%类似,在特殊的使用场景会起到更好的作用。当正确掌握这几个操作符后,你一定会爱不释手的,快去把所有的代码都重构吧,砍掉原来大段冗长的代码是一件多么令人激动的事情啊。

magrittr的项目主页:https://github.com/smbache/magrittr

2. magrittr安装

本文所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

magrittr是在CRAN发布的标准库,安装起来非常简单,2条命令就可以了。


 
 
  1. ~ R
  2. > install.packages( 'magrittr')
  3. > library(magrittr)

3. magrittr包的使用

对于magrittr包的使用,其实就是掌握这4个操作符的用法,向右操作符%>%, 向左操作符%T>%, 解释操作符%$% 和 复合赋值操作符%<>%。

3.1 %>% 向右操作符(forward-pipe operator)

%>%是最常用的一个操作符,就是把左侧准备的数据或表达式,传递给右侧的函数调用或表达式进行运行,可以连续操作就像一个链条一样。

现实原理如下图所示,使用%>%把左侧的程序的数据集A传递右侧程序的B函数,B函数的结果数据集再向右侧传递给C函数,最后完成数据计算。

mag1

比如,我们要做下面的事情。(这是一个YY的需求。)

  1. 取10000个随机数符合,符合正态分布。
  2. 求这个10000个数的绝对值,同时乘以50。
  3. 把结果组成一个100*100列的方阵。
  4. 计算方阵中每行的均值,并四舍五入保留到整数。
  5. 把结果除以7求余数,并话出余数的直方图。

我们发现上面的5个过程是连续的,正常的代码我要怎么实现呢。


 
 
  1. # 设置随机种子
  2. > set.seed( 1)
  3. # 开始
  4. > n1<-rnorm( 10000) # 第1步
  5. > n2<- abs(n1)* 50 # 第2步
  6. > n3<-matrix(n2,ncol = 100) # 第3步
  7. > n4<-round(rowMeans(n3)) # 第4步
  8. > hist(n4%% 7) # 第5步

输出的直方图:

01

上面的代码写法是,每一行实现一个条件,但中间多了不少的临时变量。再看另外一种的写法,括号包一切。


 
 
  1. # 设置随机种子
  2. > set.seed( 1)
  3. > hist( round(rowMeans(matrix( abs(rnorm( 10000))* 50,ncol= 100)))%% 7)

输出的直方图:

02

我分别用两种常见的代码风格,实现了我们的需求。再看看%>%的方式,有多么的不一样。


 
 
  1. # 设置随机种子
  2. > set.seed( 1)
  3. # 开始
  4. > rnorm( 10000) %>%
  5. + abs %>% `*` ( 50) %>%
  6. + matrix(ncol= 100) %>%
  7. + rowMeans %>% round %>%
  8. + `%%`( 7) %>% hist

输出的直方图:

03

一行代码,不仅搞定所有的事情,而且结构清楚,可读性非常强。这就是管道代码风格,带来的优雅和简约。

3.2 %T>% 向左操作符(tee operator)

%T>%向左操作符,其实功能和 %>% 基本是一样的,只不过它是把左边的值做为传递的值,而不是右边的值。这种情况的使用场景也是很多的,比如,你在数据处理的中间过程,需要打印输出或图片输出,这时整个过程就会被中断,用向左操作符,就可以解决这样的问题。

现实原理如下图所示,使用%T>%把左侧的程序的数据集A传递右侧程序的B函数,,B函数的结果数据集不再向右侧传递,而是把B左侧的A数据集再次向右传递给C函数,最后完成数据计算。

mag2

我们把上面的需求稍微进行调整,在最后增加一个要求,就会用到向左操作符。

  1. 取10000个随机数符合,符合正态分布。
  2. 求这个10000个数的绝对值,同时乘以50。
  3. 把结果组成一个100*100列的方阵。
  4. 计算方阵中每行的均值,并四舍五入保留到整数。
  5. 把结果除以7求余数,并话出余数的直方图。
  6. 对余数求和

由于输出直方图后,返回值为空,那么再继续管道,就会把空值向右进行传递,这样计算最后一步时就会出错。这时我们需求的是,把除以7的余数向右传递给最后一步求和,那么就可以用到 %T>% 了

直接使用%>%向右传值,出现异常。


 
 
  1. > set.seed( 1)
  2. > rnorm( 10000) %>%
  3. + abs %>% `*` ( 50) %>%
  4. + matrix(ncol= 100) %>%
  5. + rowMeans %>% round %>%
  6. + `%%`( 7) %>% hist %>% sum
  7. Error in sum(.) : invalid 'type' (list) of argument

使用 %T>% 把左边的值,再向右传值,则结果正确。


 
 
  1. > rnorm( 10000) %>%
  2. + abs %>% `*` ( 50) %>%
  3. + matrix(ncol= 100) %>%
  4. + rowMeans %>% round %>%
  5. + `%%`( 7) %T>% hist %>% sum
  6. [ 1] 328

3.3 %$% 解释操作符(exposition pipe-operator)

%$% 的作用是把左侧数据的属性名传给右侧,让右侧的调用函数直接通过名字,就可以获取左侧的数据。比如,我们获得一个data.frame类型的数据集,通过使用 %$%,在右侧的函数中可以直接使用列名操作数据。

现实原理如下图所示,使用%$%把左侧的程序的数据集A传递右侧程序的B函数,同时传递数据集A的属性名,作为B函数的内部变量方便对A数据集进行处理,最后完成数据计算。

mag3

下面定义一个3列10行的data.frame,列名分别为x,y,z,或缺x列大于5的数据集。使用 %$% 把列名x直接传到右侧进行判断。这里.代表左侧的完整数据对象。一行代码就实现了需求,而且这里不需要显示的定义中间变量。


 
 
  1. > set.seed( 1)
  2. > data.frame(x= 1: 10,y=rnorm( 10),z=letters[ 1: 10]) %$% .[which(x> 5),]
  3. x y z
  4. 6 6 -0.8204684 f
  5. 7 7 0.4874291 g
  6. 8 8 0.7383247 h
  7. 9 9 0.5757814 i
  8. 10 10 -0.3053884 j

如果不使用%$%,我们通常的代码写法为:


 
 
  1. > set.seed(1)
  2. > df<-data.frame(x=1:10,y=rnorm(10),z=letters[1:10])
  3. > df[ which(df $x>5),]
  4. x y z
  5. 6 6 -0.8204684 f
  6. 7 7 0.4874291 g
  7. 8 8 0.7383247 h
  8. 9 9 0.5757814 i
  9. 10 10 -0.3053884 j

从代码中可以发现,通常的写法是需要定义变量df的,df一共要被显示的使用3次,就是这一点点的改进,会让代码看起来更干净。

3.4 %<>% 复合赋值操作符(compound assignment pipe-operator)

%<>%复合赋值操作符, 功能与 %>% 基本是一样的,对了一项额外的操作,就是把结果写到左侧对象。比如,我们需要对一个数据集进行排序,那么需要获得排序的结果,用%<>%就是非常方便的。

现实原理如下图所示,使用%<>%把左侧的程序的数据集A传递右侧程序的B函数,B函数的结果数据集再向右侧传递给C函数,C函数结果的数据集再重新赋值给A,完成整个过程。

mag4

定义一个符合正态分布的100个随机数,计算绝对值,并按从小到大的顺序排序,获得并取前10个数字赋值给x。


 
 
  1. > set .seed(1)
  2. > x< -rnorm(100) %<>% abs %>% sort %>% head(10)
  3. > x
  4. [1] 0 .001105352 0 .016190263 0 .028002159 0 .039240003 0 .044933609 0 .053805041 0 .056128740
  5. [8] 0 .059313397 0 .074341324 0 .074564983

是不是太方便了,一行就实现了一连串的操作。但是这里同时有一个陷阱,需要注意一下 %<>% 必须要用在第一个管道的对象处,才能完成赋值的操作,如果不是左侧第一个位置,那么赋值将不起作用。


 
 
  1. > set .seed(1)
  2. > x< -rnorm(100)
  3. # 左侧第一个位置,赋值成功
  4. > x %<>% abs %>% sort %>% head(10)
  5. > x
  6. [1] 0 .001105352 0 .016190263 0 .028002159 0 .039240003 0 .044933609 0 .053805041 0 .056128740
  7. [8] 0 .059313397 0 .074341324 0 .074564983
  8. # 左侧第二个位置,结果被直接打印出来,但是 x的值没有变
  9. > x %>% abs %<>% sort %>% head(10)
  10. [1] 0 .001105352 0 .016190263 0 .028002159 0 .039240003 0 .044933609 0 .053805041 0 .056128740
  11. [8] 0 .059313397 0 .074341324 0 .074564983
  12. > length( x)
  13. [1] 10
  14. # 左侧第三个位置,结果被直接打印出来,但是 x的值没有变
  15. > x %>% abs %>% sort %<>% head(10)
  16. [1] 0 .001105352 0 .016190263 0 .028002159 0 .039240003 0 .044933609 0 .053805041 0 .056128740
  17. [8] 0 .059313397 0 .074341324 0 .074564983
  18. > length( x)
  19. [1] 10

4. magrittr包的扩展功能

我们已经了解了magrittr包的4个操作符的使用,除了操作符,我们再看一下magrittr还有哪些功能。

  • 符号操作符定义
  • %>%对代码块的传递
  • %>%对函数的传递

    4.1 符号操作符定义

    为了让链条传递看起来更友好,magrittr对于常见的计算符号操作符进行的重新定义,让每个操作都对应用一个函数,这样所有的传递调用代码都是风格统一的。比如,add()函数和`+`是等价的。

    下面列出对应的列表:

    
       
       
    1. extract `[`
    2. extract2 `[[`
    3. inset `[<-`
    4. inset2 `[[<-`
    5. use_series `$`
    6. add `+`
    7. subtract `-`
    8. multiply_by `*`
    9. raise_to_power `^`
    10. multiply_by_matrix `%*%`
    11. divide_by `/`
    12. divide_by_int `%/%`
    13. mod `%%`
    14. is_in `%in%`
    15. and `&`
    16. or `|`
    17. equals `==`
    18. is_greater_than `>`
    19. is_weakly_greater_than `>=`
    20. is_less_than `<`
    21. is_weakly_less_than `<=`
    22. not ( `n'est pas`) `!`
    23. set_colnames `colnames<-`
    24. set_rownames `rownames<-`
    25. set_names `names<-`

    我们来看一下使用的效果。对一个包括10个随机数的向量的先*5再+5。

    
       
       
    1. # 使用符号的写法
    2. > set .seed(1)
    3. > rnorm(10) %>% `*`(5) %>% `+`(5)
    4. [1] 1 .8677309 5 .9182166 0 .8218569 12 .9764040 6 .6475389 0 .8976581 7 .4371453 8 .6916235
    5. [9] 7 .8789068 3 .4730581
    6. # 使用函数的写法
    7. > set .seed(1)
    8. > rnorm(10) %>% multiply_by(5) %>% add(5)
    9. [1] 1 .8677309 5 .9182166 0 .8218569 12 .9764040 6 .6475389 0 .8976581 7 .4371453 8 .6916235
    10. [9] 7 .8789068 3 .4730581

    上面计算结果是完全一样的,用函数替换了符号。其实,这种转换的操作在面向对象的封装时是非常有用的,像hibernate封装了所有的SQL,XFire封装了WebServices协议等。

    4.2 %>%传递到代码块

    有些时候,我们对同一个数据块的要进行次行的处理,一条语句是很难完成的,这些就需要一个代码块也进行处理。把数据集传递到{}代码块中,传入的数据集以.来表示,通过一段代码来完成操作,而不是一句话完成操作。

    比如,对一个包括10个随机数的向量的先*5再+5,求出向量的均值和标准差,并从小到大排序后返回前5条。

    
       
       
    1. > set.seed(1)
    2. > rnorm(10) %>%
    3. + multiply_by(5) %>%
    4. + add(5) %>%
    5. + {
    6. + cat("Mean:", mean(.),
    7. + "Var:", var(.), "\n")
    8. + sort(.) %>% head
    9. + }
    10. Mean: 5.661014 Var: 15.23286
    11. [1] 0.8218569 0.8976581 1.8677309 3.4730581 5.9182166 6.6475389

    通过{}包装的代码块,就可以很方便的完成多少处理的复杂操作。

    4.3 %>%传递到函数

    传递到函数和传递到代码块设计是类似的,是把一个数据集传给一个匿名函数,进行复杂的数据数据的操作。在这里,我们会显示的定义数据集的名字作为匿名函数的参数。

    比如,对鸢尾花数据集进行处理,只保留第一行和最后一行作为结果。

    
       
       
    1. > iris %>%
    2. + ( function(x) {
    3. + if (nrow(x) > 2)
    4. + rbind(head(x, 1), tail(x, 1))
    5. + else x
    6. + })
    7. Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    8. 1 5.1 3.5 1.4 0.2 setosa
    9. 150 5.9 3.0 5.1 1.8 virginica

    这里x就是iris数据集,作为了函数的显示参数,被应用于后续的数据处理过程。

    通过对magrittr的学习,我们掌握了一些特殊的R语言代码的编程技巧,用magrittr包写出的R语言程序,与传统的R语言代码是有区别,可以你的程序很简单、很高效。


转载自:http://blog.csdn.net/fairewell/article/details/72878107



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R语言中的管道操作 的相关文章

  • Merkle树介绍

    默克尔树 Merkle树 又叫哈希树 是区块链数据存储运用到的一个重要的技术算法 简单来说 哈希树 默克尔树 中 每个节点都标有一个数据块的加密哈希值 哈希树可以用来验证任何一种在计算机中和计算机之间存储 处理和传输的数据 它们可以确保在点
  • linux ss命令详解

    ss 是 Socket Statistics 的缩写 ss 命令可以用来获取 socket 统计信息 它显示的内容和 netstat 类似 但 ss 的优势在于它能够显示更多更详细的有关 TCP 和连接状态的信息 而且比 netstat 更
  • DispatcherServlet是如何进行初始化的呢?

    转自 DispatcherServlet是如何进行初始化的呢 下文笔者讲述DispatcherServlet的初始化顺序 如下所示 Web容器启动时将调用HttpServletBean的init方法 public abstract clas
  • 蓝桥杯真题:乘积尾零

    题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 如下的 10 行数据 每行有 10 个整数 请你求出它们的乘积的末尾有多少个零 5650 4542 3554 473 946 4114 3871 9073 9
  • java 通过url取得文件返回InputStream类型数据的工具类

    通过url取得文件返回InputStream类型数据 author gugf public class HttpUtils 通过图片url返回图片Bitmap param url return public static InputStre
  • 基于RTMP实现Linux

    背景 Windows操作系统自问世以来 以其简单易用的图形化界面操作受到大众追捧 为计算机的普及 科技的发展做出了不可磨灭的功绩 也慢慢的成为人们最依赖的操作系统 在中国 90 以上的办公环境都是Windows 学校和各种培训班的培训内容也
  • ruoyi导入excel报错数据越界

    一 报错截图 二 报错原因 实体类 三 修改方式 将实体类Excel注释 修改去掉 readConverterExp部分 重新导入后成功 四 出错原因
  • 计算机的内存

    物理内存 内存是电脑的一个硬件组成部分 从单片机的组成我们可以看到 CPU 内存和输入输出接口 就组成一个完整的电脑 其他统统属于外设 内存是可以被CPU通过总线进行操作的 也就是与CPU之间有总线相连接的 电脑所有的输入输出 都是要从内存
  • Nodejs

    一 是什么 在浏览器事件循环 opens new window 中 我们了解到javascript在浏览器中的事件循环机制 其是根据HTML5定义的规范来实现 而在NodeJS中 事件循环是基于libuv实现 libuv是一个多平台的专注于
  • 帮我写一段库存管理的程序

    答 下面是一段库存管理的程序 定义变量 int 库存总量 0 计算库存总量 for int i 0 i lt 产品列表 length i 库存总量 库存总量 产品列表 i 库存数量 打印库存总量 System out println 库存总
  • 详解Win10家庭版/专业版/企业版功能区别

    Win10版本到底有哪些 Win10的各版本有什么不同 差别和区别 Win10旗舰版有木有 Win10最好的版本是哪个 我应该用哪个版本的Windows10 之前曾经在今年更早时间解释了Win10各个版本之间有什么差别和不同之处 但是在Wi
  • Java 线程

    线程 创建线程的方式及实现 https www cnblogs com 3s540 p 7172146 html sleep join yield 有什么区别 https blog csdn net xiangwanpeng article
  • 怎么让chatGPT写作文-ChatGPT如何写作

    chatGPT写文章攻略 ChatGPT 可以生成文章的概要 但生成的文章质量和效率与输入的信息质量和有效性有着重要关系 以下是使用 ChatGPT 写作时需要注意的攻略 确定写作主题和目的 在开始使用 ChatGPT 进行写作前 需要明确
  • Office2019 Office2016 Office2010 Office365 系列各版本下载

    蓝点网出品 必属精品 Office Tools Plus 相信很多博文都有写教程 然鹅 软件里就有 很详细 实在激活不了加群 有小姐姐远程技术支持还免费 之前的那篇博文链接失效且因为下载链接的原因被删 这回 下载链接见评论
  • linux查看ipynb文件

    linux查看ipynb文件 使用jupyter查看 使用jupyter查看 安装 pip install jupyter 添加配置好的环境到jupyter notebook的kernel中 python m ipykernel insta
  • 1016 部分A+B

    正整数 A 的 DA 为 1 位整数 部分 定义为由 A 中所有 DA 组成的新整数 PA 例如 给定 A 3862767 DA 6 则 A 的 6 部分 PA 是 66 因为 A 中有 2 个 6 现给定 A DA B DB 请编写程序计
  • python自动化测试web页面组成_Selenium自动化测试网页

    今天想跟大家分享的是 关于selenium的自动化测试一些基础的东西 安装环境 1 Python环境 安装完成后通过Windows命令提示符CMD输入 python 查看是否安装成功 2 安装setuptools与pip setuptool
  • markdown 矩阵

    无括号 begin matrix 1 2 3 4 5 6 7 8 9 end matrix 1 2
  • VUE3 + Ant Design Vue构建

    步骤 node 和 npm 已安装前提下 1 安装vue 安装vue脚手架 npm install g vue cli 安装vue vue create 项目名 2 安装Ant Design Vue 最好安装的时候不要用pnpm 我用pnp
  • 内存分区-包含bss段data段

    都说四大内存分区 代码区 全局区 堆区 栈区 但是这个说法比较粗略 其实从低地址 gt 高地址 依次为代码区 常量 全局变量和静态变量 bss段 堆区 栈区 代码区 常量 const define 全局区 data段 静态变量和初始化的全局

随机推荐

  • RabbitMQ--基础--11.2--幂等性,惰性队列

    RabbitMQ 基础 11 2 幂等性 惰性队列 1 幂等性 就是重复消费消息 1 1 消息重复消费 消费者在消费MQ中的消息时 MQ已把消息发送给消费者 消费者在给MQ返回ack时网络中断 故MQ未收到确认消息 该条消息会重新发给其它的
  • 线程池的使用(7种创建方法)

    目录 1 固定数量的线程池 a 线程池返回结果 b 定义线程池名称或优先级 2 带缓存的线程池 3 执 定时任务 a 延迟执 次 b 固定频率执 c scheduleAtFixedRate VS scheduleWithFixedDelay
  • VS中后台运行设置

    背景知识 操作系统装载应用程序后 做完初始化工作就转到程序的入口点执行 程序默认入口点实际上是由连接程序设置的 不同的连接器选择的入口函数也不尽相同 在VC 下 连接器对控制台程序设置的入口函数是 mainCRTStartup mainCR
  • 【Linux】linux常用基本命令

    Linux中许多常用命令是必须掌握的 这里将我学linux入门时学的一些常用的基本命令分享给大家一下 希望可以帮助你们 这个是我将鸟哥书上的进行了一下整理的 希望不要涉及到版权问题 1 显示日期的指令 date 2 显示日历的指令 cal
  • 熔断与降级的区别

    原文 熔断与降级的区别 前言 今天在博客上看到一句话 在分布式系统中 限流和熔断是处理并发的两大利器 关于限流和熔断 需要记住一句话 客户端熔断 服务端限流 发现为什么是限流和熔断 而不是限流和降级 于是就有了这篇文章 相似处 1 目的一致
  • Zerotier 搭建手册(含Moon节点)

    一 前言 没有申请到公网IP 内网穿透只好选用zerotier 好处就是P2P端点的带宽 不受云服务器和FRP带宽限制 打算用zerotier组建了笔记本 NAS 手机三个端 满足NAS在IPV4大内网环境下的相互访问 zerotier主服
  • mysql-5.0.24a-win32.zip_go.sum · skymysky/Nightingale - Gitee.com

    bazil org fuse v0 0 0 20160811212531 371fbbdaa898 go mod h1 Xbm BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8 cloud google com
  • C++ ifstream open 读取txt文件出现中文乱码的解决方法

    由于编解码的问题 txt读写会出现中文乱码 打开txt文件 点另存为 可看到编码方式有 编码方式为UTF 8时 会出现中文乱码 将编码方式换为ANSI时 问题解决
  • spring boot的两种部署方式

    spring boot的两种部署方式 文章目录 spring boot的两种部署方式 前言 一 jar包部署 二 war包部署 jar包和war包方式对比 前言 springboot的打包方式有很多种 有打成war的 有打成jar的 也有直
  • 使用Matlab设计数字滤波器,从原理到代码

    目录 0 前言 1 数字滤波器的设计方法概述 2 IIR数字滤波器的设计方法 2 1 模拟滤波器设计 2 1 1 巴特沃斯滤波器设计 2 1 2 切比雪夫滤波器设计 2 1 3 椭圆滤波器设计 2 2 模拟滤波器转数字滤波器 2 2 1 冲
  • 【Android】Android6.0+ 动态申请权限

    Android 6 0 SDK 版本号大于23后 对于普通权限可以在AndroidMinifest xml文件中可以直接使用 而对于那些危险权限 如 定位权限 通话 发送短信等 需要动态申请权限 下面是一个通过高德定位的案例 MainAct
  • request对象对请求体,请求头参数的解析

    1 请求体参数解析 1 1 GET请求 1 1 1 请求url中 xxx xxx格式为查询字符串参数 通过request GET获取请求参数 1 1 2 请求url中 xxx 2 xxx格式为路径参数 通过request GET获取 1 1
  • IDEA常用配置之双斜杠注释紧跟代码头

    文章目录 双斜杠注释改成紧跟代码头 双斜杠注释改成紧跟代码头
  • qRegisterMetaType-Qt中注册定义类型

    概述 如果想要我们自己自定义的类型也可以有 Qt 自己类型的功能的话 就必须注册我们的类型到 Qt 中 这样才可以在信号和槽的通讯机制中使用我们的自定义的类型 Q DECLARE METATYPE 被 Q DECLARE METATYPEQ
  • QMetaObject::connectSlotsByName: No matching signal for问题的解决方法

    之前是用转到槽的方式添加信号回调 现在发现结构混乱 改为手动connect 删掉之前的回调函数后 再编译 找到报错的地方 删除case 然后自己添加connect 注意此时代码运行会报 QMetaObject connectSlotsByN
  • java二维码工具类,中间带LOGO的,很强大 .

    java view plain copy print package com util cccm import java awt BasicStroke import java awt Graphics import java awt Gr
  • GAMES101-现代计算机图形学学习笔记(作业06)

    参考 https blog csdn net qq 36242312 article details 115495482 思路 上节课的代码 void Renderer Render const Scene scene std vector
  • Vue 核心插件 Vuex (一)

    目录 Vuex 是什么 Vuex 使用场景 Vuex的优势 Vuex的安装和使用 Vuex的安装 Vuex的配置使用 Vuex 是什么 Vuex 是一个专为 Vue js 应用程序开发的状态管理模式 库 它采用集中式存储管理应用的所有组件的
  • citespace的操作流程

    1 下载citespace 下载成功的前提是必须要有Java 参照网上的下载流程 建议bilibili上查看 2 打开citespace 1 2 选择keep using this version 3 弹出来窗口 选择Agree 一般是会弹
  • R语言中的管道操作

    前言 使用R语言进行数据处理是非常方便的 几行代码就可以完成很复杂的操作 但是 对于数据的连续处理 还是有人觉得代码不好看 要么是长长的函数嵌套调用 有点像Lisp感觉 括号包一切 要么就是每次操作赋值一个临时变量 啰嗦 为什么就不能像Li