如何在ExomeDepth的R脚本中调用Bash变量?
问题描述
我之前用包含SLURM数组的Bash脚本处理文件,运行正常,脚本如下:
#!/bin/bash --login #SBATCH --ntasks=1 #SBATCH --ntasks-per-node=1 #SBATCH -p htc #SBATCH --mail-type=ALL # Mail events (NONE, BEGIN, END, FAIL, ALL) #SBATCH --array=1-64 module load parallel module load tool EXOME_IDs_FILE=/home/bestcoverage_E036 INPUTFILE=/home/{}.bam sed -n "${SLURM_ARRAY_TASK_ID}p" $EXOME_IDs_FILE | parallel -j 1 "tool $INPUTFILE"
现在需要改用R的ExomeDepth工具,官方示例代码如下:
data(exons.hg19) my.counts <- getBamCounts(bed.frame = exons.hg19, bam.files = my.bam, include.chr = FALSE, referenceFasta = fasta)
我希望把Bash中定义的INPUTFILE、HG38、INPUTBEDFILE等变量传入R代码中,但尝试的脚本无法正常运行,请问如何实现Bash变量在R代码中的调用?我尝试的脚本如下:
#!/bin/bash --login #SBATCH --ntasks=1 #SBATCH --ntasks-per-node=1 #SBATCH -p htc #SBATCH --mail-type=ALL # Mail events (NONE, BEGIN, END, FAIL, ALL) #SBATCH --array=1-64 module load parallel module load tool EXOME_IDs_FILE=/home/bestcoverage_E036 INPUTFILE=/home/{}.bam HG38=/home/hg38.fasta INPUTBEDFILE=/home/inputbed.bed sed -n "${SLURM_ARRAY_TASK_ID}p" $EXOME_IDs_FILE | parallel -j 1 "data($INPUTBEDFILE) my.counts <- getBamCounts(bed.frame = $INPUTBEDFILE, bam.files = $INPUTFILE, include.chr = FALSE, referenceFasta = $HG38)
解决方案
你尝试的脚本存在几个关键问题,以下是修正后的实现方式:
1. 核心问题说明
- R的
data()函数是加载内置数据集的,不能直接读取外部BED文件,需要用专门的文件读取函数 - Bash变量传入R时要作为字符串处理,必须加引号,同时要避免Bash提前解析R代码里的变量
- 必须通过
R -e或Rscript命令来执行R代码逻辑
2. 修正后的完整Bash+R脚本
#!/bin/bash --login #SBATCH --ntasks=1 #SBATCH --ntasks-per-node=1 #SBATCH -p htc #SBATCH --mail-type=ALL #SBATCH --array=1-64 # 加载环境模块,替换成你实际的R版本 module load parallel module load R/4.2.0 EXOME_IDs_FILE=/home/bestcoverage_E036 HG38=/home/hg38.fasta INPUTBEDFILE=/home/inputbed.bed # 读取对应行的样本ID,并行处理 sed -n "${SLURM_ARRAY_TASK_ID}p" $EXOME_IDs_FILE | parallel -j 1 ' # 替换占位符为当前样本的BAM路径 BAM_PATH=/home/{}.bam OUTPUT_PATH={}_exome_counts.rds # 调用R执行分析,通过嵌套引号传递Bash变量 R -e '\'' # 加载所需R包,提前确保已安装 library(ExomeDepth) library(rtracklayer) # 读取BED文件为R可用的格式 bed_data <- import("'"$INPUTBEDFILE"'") # 运行ExomeDepth的计数函数 sample_counts <- getBamCounts( bed.frame = bed_data, bam.files = "'"$BAM_PATH"'", include.chr = FALSE, referenceFasta = "'"$HG38"'" ) # 保存结果到单独文件,避免样本间干扰 saveRDS(sample_counts, file = "'"$OUTPUT_PATH"'") '\'' '
3. 关键修正点
- 变量传递格式:用
'"$VAR_NAME"'的嵌套引号格式,让Bash先解析变量,再传递给R作为字符串参数 - BED文件读取:用
rtracklayer::import()读取BED文件(需提前安装rtracklayer包),如果不需要GRanges对象,也可以用read.table()手动构建数据框 - 结果隔离:每个样本的计数结果保存为独立的RDS文件,方便后续批量分析
4. 备选方案:分离R脚本
如果觉得命令行里的R代码可读性差,可以把R逻辑单独写成脚本文件:
独立R脚本 exomedepth_count.R
# 读取命令行传入的参数 args <- commandArgs(trailingOnly = TRUE) bed_file <- args[1] bam_file <- args[2] fasta_file <- args[3] output_file <- args[4] # 加载依赖包 library(ExomeDepth) library(rtracklayer) # 读取BED文件 bed_frame <- import(bed_file) # 计算外显子计数 count_result <- getBamCounts( bed.frame = bed_frame, bam.files = bam_file, include.chr = FALSE, referenceFasta = fasta_file ) # 保存结果 saveRDS(count_result, file = output_file)
对应的Bash脚本
#!/bin/bash --login #SBATCH --ntasks=1 #SBATCH --ntasks-per-node=1 #SBATCH -p htc #SBATCH --mail-type=ALL #SBATCH --array=1-64 module load parallel module load R/4.2.0 EXOME_IDs_FILE=/home/bestcoverage_E036 HG38=/home/hg38.fasta INPUTBEDFILE=/home/inputbed.bed R_SCRIPT_PATH=/path/to/exomedepth_count.R sed -n "${SLURM_ARRAY_TASK_ID}p" $EXOME_IDs_FILE | parallel -j 1 ' BAM_FILE=/home/{}.bam OUTPUT_FILE={}_counts.rds # 通过Rscript传递参数给独立R脚本 Rscript '"$R_SCRIPT_PATH"' '"$INPUTBEDFILE"' '"$BAM_FILE"' '"$HG38"' '"$OUTPUT_FILE"' '
内容的提问来源于stack exchange,提问作者Amy Houseman
相关产品推荐
相关产品推荐

