运行耗时比较长的代码就需要后台运行了

2023-09-04 15:39:11 浏览数 (1)

在Linux或者Unix系统中,你可以使用nohup命令和&符号来在后台运行R脚本。这样即使你关闭了终端,你的R脚本也会继续运行。以下是一个例子,假设你的R脚本名为myscript.R

代码语言:javascript复制
nohup Rscript myscript.R > output.txt &

在这个命令中:

  • nohup命令让你的R脚本在后台运行,并且即使你关闭了终端也不会停止。
  • Rscript是一个可以运行R脚本的命令行工具。
  • myscript.R是你要运行的R脚本。
  • >符号将你的R脚本的输出重定向到一个文件中,这个例子中是output.txt
  • &符号让你的R脚本在后台运行。

注意,你需要确保你的R脚本在运行时不需要任何用户交互。否则,你的R脚本可能会在需要用户输入时停止运行。

这个时候如何编写名为myscript.R的R脚本内容就是大家需要考虑的了。假设我们有一个简单的R脚本,名为myscript.R,它的任务是读取一个CSV文件,计算一些统计数据,然后将结果保存到另一个CSV文件。以下是myscript.R的可能内容:

代码语言:javascript复制
# Load necessary library
library(dplyr)

# Read the data from a CSV file
data <- read.csv("input.csv")

# Calculate the mean and standard deviation of each numeric column
stats <- data %>%
  summarise_all(list(mean = mean, sd = sd), na.rm = TRUE)

# Write the results to a new CSV file
write.csv(stats, "output.csv")

这个脚本首先加载了dplyr库,然后读取了名为input.csv的CSV文件中的数据。然后,它使用dplyrsummarise_all函数计算了每个数值列的平均值和标准差。最后,它将结果写入到名为output.csv的新CSV文件中。

你可以使用以下命令在后台运行这个脚本:

代码语言:javascript复制
nohup Rscript myscript.R > output.txt &

这个命令将启动一个新的后台进程来运行myscript.R脚本,并将所有的输出(包括任何的错误信息)重定向到output.txt文件。即使你关闭了终端,这个脚本也会继续运行,直到它完成任务。

虽然我们的R脚本在运行的时候不能有交互,但是我们可以预先传入参数。R脚本可以接受命令行参数。比如上面的脚本,我们在文件里面写入了读取的文件是input.csv,但是很多情况下,我们并不想每次打开脚本去修改灵敏度内容,所以我们会使用一个参数给这个脚本,来每次个性化的赋予文件名字。

你可以使用commandArgs函数来获取这些参数。这个函数返回一个字符向量,其中包含了传递给脚本的所有参数。例如,假设你有一个名为myscript.R的脚本,你想让它接受两个参数:输入文件的名称和输出文件的名称。你可以像下面这样修改你的脚本:

代码语言:javascript复制
# Load necessary library
library(dplyr)

# Get the command line arguments
args <- commandArgs(trailingOnly = TRUE)

# Read the data from the input CSV file
data <- read.csv(args[1])

# Calculate the mean and standard deviation of each numeric column
stats <- data %>%
  summarise_all(list(mean = mean, sd = sd), na.rm = TRUE)

# Write the results to the output CSV file
write.csv(stats, args[2])

在这个脚本中,args[1]是输入文件的名称,args[2]是输出文件的名称。你可以通过在命令行中提供这些参数来运行你的脚本,如下所示:

代码语言:javascript复制
bashCopy code
nohup Rscript myscript.R input.csv output.csv > output.txt &

在这个命令中,input.csv是传递给myscript.R的第一个参数,output.csv是第二个参数。这些参数在脚本中通过args[1]args[2]来访问。

可以看到,这个脚本就非常方便了,自己指定了输入输出文件,是 input.csv output.csv,每次运行这个脚本都是可以自定义修改的。

一个比较耗时的R脚本案例:

单细胞转录组数据分析里面的高级分析,绝大部分都会比较耗时,我们都分享过:

  • 10x官网下载pbmc3k数据集走RNA速率上下游分析实战
  • pyscenic的转录因子分析结果展示之各个单细胞亚群特异性激活转录因子
  • pyscenic的转录因子分析结果展示之5种可视化
  • 使用cytoTRACE评估不同单细胞亚群的分化潜能
  • 明明是一个热图就能搞定的事情为什么要复杂到蛋壳图呢
  • 基于非负矩阵分解的单细胞降维聚类分群

比如肿瘤单细胞里面的上皮细胞通常是需要走inferCNV来判断它里面的具体的单细胞的恶性情况,我就会写如下所示的R语言脚本程序:

代码语言:javascript复制
load(file = 'epi_sce.Rdata')
epiMat=as.data.frame(GetAssayData(sce,
                                  slot='counts',assay='RNA'))
load('../reference_mat.Rdata')

dat=cbind(epiMat,mastMat,BcellsMat)
groupinfo=data.frame(v1=colnames(dat),
                     v2=c(rep('epi',ncol(epiMat)),
                          rep('spike-mast',300),
                          rep('ref-mast',500),
                          rep('spike-Bcells',300),
                          rep('ref-Bcells',500)))

library(AnnoProbe)
geneInfor=annoGene(rownames(dat),"SYMBOL",'human')
colnames(geneInfor)
geneInfor=geneInfor[with(geneInfor, order(chr, start)),c(1,4:6)]
geneInfor=geneInfor[!duplicated(geneInfor[,1]),]
length(unique(geneInfor[,1]))
head(geneInfor)
## 这里可以去除性染色体
# 也可以把染色体排序方式改变
dat=dat[rownames(dat) %in% geneInfor[,1],]
dat=dat[match( geneInfor[,1], rownames(dat) ),] 
dim(dat)
expFile='expFile.txt'
write.table(dat,file = expFile,sep = 't',quote = F)
groupFiles='groupFiles.txt'
head(groupinfo)
write.table(groupinfo,file = groupFiles,sep = 't',quote = F,col.names = F,row.names = F)
head(geneInfor)
geneFile='geneFile.txt'
write.table(geneInfor,file = geneFile,sep = 't',quote = F,col.names = F,row.names = F)

options(stringsAsFactors = F)
library(Seurat)
library(gplots)
library(ggplot2)

expFile='expFile.txt' 
groupFiles='groupFiles.txt'  
geneFile='geneFile.txt'

# duplicate 'row.names' are not allowed
library(infercnv)
infercnv_obj = CreateInfercnvObject(raw_counts_matrix=expFile,
                                    annotations_file=groupFiles,
                                    delim="t",
                                    gene_order_file= geneFile,
                                    ref_group_names=c("ref-mast",'ref-Bcells'))  ## 这个取决于自己的分组信息里面的

 
# cutoff=1 works well for Smart-seq2, and cutoff=0.1 works well for 10x Genomics
infercnv_obj2 = infercnv::run(infercnv_obj,
                              cutoff=0.1, # cutoff=1 works well for Smart-seq2, and cutoff=0.1 works well for 10x Genomics
                              out_dir= "infercnv_output",  # dir is auto-created for storing outputs
                              cluster_by_groups=T ,   # cluster
                              hclust_method="ward.D2", plot_steps=F)
   

然后去后台批量提交:

代码语言:javascript复制
ls -d N-*|while read id;
do 
echo $id;
cd $id;
nohup Rscript ../scripts/step1-run-inferCNV.R &
cd ../
done 

每个病人的文件夹里面都有一个 epi_sce.Rdata 存放自己的上皮细胞的表达量矩阵信息,然后所有的病人都会共有同一个 reference_mat.Rdata,每个病人都会运行 infercnv程序后出图。

0 人点赞