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

在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.xdnf.cn/news/14737.html

相关文章:

  • Spring Boot整合Redis指南
  • 强化学习理论基础:从Q-learning到PPO的算法演进(2)
  • RabbitMQ RPC模式Python示例
  • go写前端打包的自动化工具
  • oracle内存参数调整
  • 【Redis】解码Redis中的list类型,基本命令,内部编码方式以及适用的场景
  • 流程管理系统技术选型避坑指南(含开源)
  • 优化 ArcPy 脚本性能
  • Jmeter并发测试和持续性压测
  • AI+实时计算如何赋能金融系统?DolphinDB 在国泰君安期货年度中期策略会的演讲
  • 鸿蒙版FlutterSDK3.27.4可以使用了
  • 报道称CoreWeave洽谈收购Core Scientific,后者涨超30%
  • 人工智能-基础篇-2-什么是机器学习?(ML,监督学习,半监督学习,零监督学习,强化学习,深度学习,机器学习步骤等)
  • 报表控件stimulsoft教程:在报表、仪表板和 PDF 表单自动生成缩略图
  • 华为云鸿蒙应用入门级开发者认证 实验(HCCDA-HarmonyOS Cloud Apps)
  • 【缓存技术】深入分析如果使用好缓存及注意事项
  • C++(模板与容器)
  • python中学物理实验模拟:斜面受力分析
  • 苍穹外卖day3--公共字段填充+新增菜品
  • python基于协同过滤的动漫推荐系统
  • 【51单片机5毫秒定时器】2022-6-1
  • Linux 内核 TCP 的核心引擎:tcp_input.c 与 tcp_output.c 的协同之道
  • Miniconda+Jupyter+PyCharm初始环境配置
  • 物联网与低代码:Node-RED如何赋能工业智能化与纵横智控的创新实践
  • 【已解决】Android Studio gradle遇到unresolved reference错误
  • 【机器学习深度学习】线性回归
  • 【thinkphp5】Session和Cache记录微信accesstoken
  • 【原创】【4】【辅助工具】基于视觉模型+FFmpeg+MoviePy实现短视频自动化二次编辑+多赛道
  • Gartner《敏捷化组织团队拓扑方法论》学习心得
  • [特殊字符]推客带货小程序解决方案——0门槛裂变营销,佣金赚不停!