当前位置: 首页 > news >正文

在shell中直接调用使用R

前言:这篇博客的内容其实是在我另外一篇博客《python、R、shell兼容》之前就整理好的,见
https://blog.csdn.net/weixin_62528784/article/details/148149416?spm=1001.2014.3001.5502,
问题是放得太久了,暂时想不起来要往下写什么了,但是也整理得差不多了,就作为后者的一个补充。

我们先以1个简单的例子来来切入

——查看帮助文档:

虽然在jupyter notebook的cell或者vscode的httpgd中都能够快速查看帮助文档,类似于Rstudio的并行界面;

但是一个函数帮助文档太长的时候,我们想看某个参数的细节就像大海捞针一样,非常的浪费时间;

如果能够用上shell的grep/awk/sed快速文本处理命令,那么这些细节上就能够快速的处理,

但是我们不打开radian或者R terminal,

我们只想在shell中展示,这样才方便利用shell强大的文本处理工具:

比如说我手头上有一段简短的代码

coef.months <- c(coef(mod.lm2)[2:12],-sum(coef(mod.lm2)[2:12]))plot(coef.months, xlab = "Month", ylab = "Coefficient",xaxt = "n", col = "blue", pch = 19, type = "o")
axis(side = 1, at = 1:12, labels = c("J", "F", "M", "A","M", "J", "J", "A", "S", "O", "N", "D"))

其实就是绘制一个最小二乘法拟合之后的回归模型的系数曲线,

我在绘制简单的线图的时候不想使用原本的x轴标度,而是自定义,

假设我突然忘了plot函数中xaxt参数的用法,但是我又不想从头打开文档去找,哪怕文档只有100多行,我就想在shell中快速查找,使用grep命令。

下面这条命令想必大家都很熟悉,就是在shell中执行R命令的格式:

Rscript -e 'R command'R -e 'R command'# 示例
Rscript -e 'help("plot")' | grep -i -C 5 "xaxt"

grep能用的花样就很多了:

比如说-i忽略大小写,-C查看上下文,这样我就知道xaxt是禁用自带轴标度了

所以在shell中直接使用R命令的方式(不考虑进入R terminal,也不考虑R内核的其他实现方式)

一,Rscript命令模式(或R命令模式)

1,linux下直接执行R命令

Rscript	 -e 'R command'
R -e 'R command'

简单的例子:

2,linux下执行R脚本(或静默执行R脚本)

R --no-save < terminalR.R
R --no-save -q < terminalR.R
R --no-save --slave < terminalR.R

举个简单的例子:比如说是hello world

总之<符号是必须的:

但是这里还是要注意一下Rscript和R命令的区别:

二,R script 脚本化(便于直接在shell脚本中和python程序、shell命令行等并行、串行、联动)

脚本化是一种对用户友好的封装,不仅能提高程序的健壮性,还能很容易的集成到分析流程中。

——》统一推荐使用Rscript命令行

1,R 脚本简介 Rscript

脚本化,就是把程序写成有输入和输出的独立程序文件。就像shell的 ls 命令, 比对软件 STAR 一样,用户只需要调用脚本名字、给出参数,程序就能判断参数是否合法,并返回结果。把程序像黑盒一样封装起来,方便用户使用,还能轻易整合到 snakemake 等流程中。

推荐使用朴素的写法,尽量只使用R核心API,依赖越少越稳定,以便其他用户复用。

推荐格式如下:# 比如说一个以使用monocle2包的脚本为例- 脚本名字以 xx.script.R 结尾。
- 开头部分写上脚本的目的,使用方法,测试环境,版本变化
- R脚本模板 # Aim: do monocle2 as a script, output to a dir
# how to use: $ Rscript this.script.R xx.Seurat.obj [outputRoot]
# Env: R 4.1.0
# version: 0.2-20240504
# version: 0.3-20240504 set parameters

2,R 脚本化相关技术

脚本内部把参数列表保存在数组 myArgs=commandArgs(TRUE) 中,下标0是该脚本文件名本身,下标1是第一个参数,以此类推。

获取的参数是字符串形式,要做算术运算需要主动转为数字形式,比如 as.numeric(str2)。

一般还需要验证参数,比如个数、类型是否正确,输出文件是否已经存在等。

(1)接收参数

# 实例(Ubuntu 24.04 + R 4.4.2)
#例1: 接收参数,并对第2个参数加100后输出
$ cat test1.R   # 先写好vim
#获取命令行参数
myArgs = commandArgs(TRUE)#myArgs是所有参数的向量
print(myArgs) 
print(class(myArgs))
message("length:", length(myArgs), ", first:", myArgs[1] )n1=as.numeric(myArgs[2])
print( n1+100 )

然后下面就是试验了:运行该脚本,并传入参数

如果传入参数个数不够,不报错,但是会计算异常,比如第二个转为数字返回NA。

总结就是:
通过 Rscript 执行R脚本。R脚本内通过 arr = commandArgs(TRUE) 接收参数,接收到的是一个数组,第一个参数的下标是1;类型为字符串,可以按需要强转。

(2)参数校验与主动报错

先检查参数个数,再检查参数类型,还要检查输出文件是否存在,如果存在是否覆盖?

主动报错,即在参数不合法时,主动抛出错误,终止程序运行,并给出错误提示或给出合理化建议。

①如果参数个数不对,则报错:

只有一个参数的时候报错了,参数长度不符合:

两个参数就正常执行了:

②如果输入(file)文件不存在,则报错

该脚本同时获取数据文件的行列数

我们先写入一个经典的base中就有的数据看看

在shell中是输出成功的,能打开该文件:

有文件时,返回行列数

我们查看一下确实没问题

没有文件时,主动报错

③如果输出(dir)文件夹不存在,则报错

测试:第二个参数是输出文件夹,不存在则报错

④stopifnot(): 脚本参数的校验,和函数参数的校验类似

# stopifnot(): If any of the expressions (in ... or exprs) are not all TRUE, 
# stop is called, producing an error message indicating the first expression which was not (all) true.

测试1: 参数个数至少2个

测试2: 参数个数不够2个则报错

(3)打印时间戳进度条

运行时间长的脚本需要进度条,以缓解用户的焦虑,告诉用户程序运行到哪了,方便用户估计还要等多久。一般有伴随着进度条直接写时分秒的,还有写已经运行时间的。

①显示时分秒的

for(i in 1:10){Sys.sleep(runif(1)*0.5+0.5)message("[",Sys.time(), "]", i)
}

②其他时间相关函数:

# 查询时区
> Sys.time() #现在的时间 [1]  "2025-03-16 23:14:12 CST"
> Sys.timezone() #查看当前时区 [1] "Asia/Shanghai"# 支持的时区
> OlsonNames() #所有R支持的时区
> grep("Shanghai", OlsonNames(), value=T)
#[1] "Asia/Shanghai"# 设置时区后,服务器R时间就和本地一致了
> Sys.setenv(TZ = "Asia/Shanghai")
> Sys.timezone() # 查看时区 "Asia/Shanghai"> Sys.time() #现在的时间和windows右下角一致了
# [1]"2025-03-16 23:15:49 CST"

参考:
https://www.cnblogs.com/emanlee/p/13900239.html

https://www.biomooc.com/R/R-script.html

http://www.lryc.cn/news/576148.html

相关文章:

  • 远眺科技工业园区数字孪生方案,如何实现智能管理升级?
  • 告别堡垒机和VPN!Teleport:下一代基础设施统一访问入口
  • CTP IC失效现象和失效原理分析
  • 利用python实现NBA数据可视化
  • np.concatenate
  • 【C/C++】C++26新特性前瞻:全面解析未来编程
  • ​​Oracle表空间全景指南:从扩容监控到碎片回收的终极实践​
  • 车载诊断架构--- 车载诊断中的引导式诊断
  • 人工智能-基础篇-3-什么是深度学习?(DL,卷积神经网络CNN,循环神经网络RNN,Transformer等)
  • 第六章 STM32内存管理
  • 学习接口自动化框架pytest有哪些好处?
  • 小程序 API 开发手册:从入门到高级应用一网打尽
  • C++学习之STL学习:vector的模拟实现
  • Java多线程与JUC
  • window显示驱动开发—DirectX 图形内核子系统(三)
  • RocketMQ 消息长轮询
  • 集群聊天服务器----CMake的使用
  • ServletConfig ServletContext
  • git add 报错UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xaf in position 42
  • 【Elasticsearch】Linux环境下安装Elasticsearch
  • spring ai入门实例
  • LangChain4j(20)——调用百度地图MCP服务
  • Python Async 编程快速入门 | 超简明异步协程指南
  • java代码规范
  • 自动化保护 AWS ECS Fargate 服务:使用 Prisma Cloud 实现容器安全
  • 阶段二开始-第一章—8天Python从入门到精通【itheima】-116节(封装)
  • 鸿蒙HarmonyOS 5小游戏实践:记忆翻牌(附:源代码)
  • DHT11 STM32 HAL驱动库 整数
  • .NetCore+Vue快速生产框架开发详细方案
  • Chrome浏览器访问https提示“您的连接不是私密连接”问题解决方案