如何将bash变量传递到R脚本

时间:2019-06-26 16:41:24

标签: r bash

我有几个R脚本,用于处理特定输入文件夹中的数据。我有几个文件夹需要运行此脚本,因此我开始编写bash脚本以遍历这些文件夹并运行这些R脚本。

我根本不熟悉R(脚本是由以前的工作人员编写的,对我而言基本上是一个黑匣子),而且我对通过脚本传递变量(尤其是涉及多种语言)没有经验。当我在此处调用source(“ $ SWS_output / Step_1_Setup.R”)时,还有一个问题-R不会将$ SWS_output读取为变量,而是将其读取为字符串。

这是我的bash脚本:

#!/bin/bash

# Inputs
workspace="`pwd`"
preprocessed="$workspace/6_preprocessed"

# Output
SWS_output="$workspace/7_SKSattempt4_results/"

# create output directory
mkdir -p $SWS_output

# Copy data from preprocessed to SWS_output
cp -a $preprocessed/* $SWS_output

# Loop through folders in the output and run the R code on each folder
for qdir in $SWS_output/*/; do
        qdir_name=`basename $qdir`
        echo -e 'source("$SWS_output/Step_1_Setup.R") \n source("$SWS_output/(Step_2_data.R") \n  q()' | R --no-save

done

我需要将变量“ qdir”传递到第二个R脚本(Step_2_data.R)中,以告诉它要处理哪个文件夹。

谢谢!

2 个答案:

答案 0 :(得分:1)

我以前的回答不完整。这是解释命令行分析的更好方法。

使用R的commandArgs函数来处理命令行参数非常容易。我写了一个小教程https://gitlab.crmda.ku.edu/crmda/hpcexample/tree/master/Ex51-R-ManySerialJobs。在集群计算中,这对我们来说非常有效。整个hpcexample存储库是开源的/免费的。

基本思想是,您可以在命令行中使用命令行参数运行R,如下所示:

R --vanilla -f r-clargs-3.R --args runI=13 parmsC="params.csv" xN=33.45

在这种情况下,我的R程序是文件r-clargs-3.R,文件将导入的参数是三个用空格分隔的元素,runIparmsCxN。您可以根据需要添加任意多个以空格分隔的参数。完全由您自己决定如何称呼它们,但是要求它们之间用空格隔开,并且等号周围不能有空格。字符串变量应加引号。

我的习惯是给参数加上后缀“ I”,以暗示它是整数,“ C”代表字符,“ N”代表浮点数。

在文件r-clargs-3.R中,包含一些代码以读取参数并对其进行排序。例如,我的教程示例

cli <- commandArgs(trailingOnly = TRUE) 
args <- strsplit(cli, "=", fixed = TRUE)

其余的工作是对args进行排序,这是我对参数进行排序最进化的节(因为它查找后缀“ I”,“ N”,“ C”和“ L”(对于逻辑)),然后将输入强制转换为正确的变量类型(除非我们用as.integer()强制转换,否则所有输入变量都是字符,等等):

for (e in args) {
    argname <- e[1]
    if (! is.na(e[2])) {
        argval <- e[2]
        ## regular expression to delete initial \" and trailing \"
        argval <- gsub("(^\\\"|\\\"$)", "", argval)
    }
    else {
        # If arg specified without value, assume it is bool type and TRUE
        argval <- TRUE
    }

    # Infer type from last character of argname, cast val
    type <- substring(argname, nchar(argname), nchar(argname))
    if (type == "I") {
        argval <- as.integer(argval)
    }
    if (type == "N") {
        argval <- as.numeric(argval)
    }
    if (type == "L") {
        argval <- as.logical(argval)
    }
    assign(argname, argval)
    cat("Assigned", argname, "=", argval, "\n")
}

这将在名为paramsCrunIxN的R会话中创建变量。

此方法的便利之处在于,相同的基本R代码可以运行100或1000 s的命令参数变量。适用于蒙特卡洛模拟等。

答案 1 :(得分:0)

感谢所有答案,他们非常有帮助。我能够找到有效的解决方案。这是我完成的脚本。

#!/bin/bash

# Inputs
workspace="`pwd`"
preprocessed="$workspace/6_preprocessed"

# Output
SWS_output="$workspace/7_SKSattempt4_results"

# create output directory
mkdir -p $SWS_output

# Copy data from preprocessed to SWS_output
cp -a $preprocessed/* $SWS_output

cd $SWS_output

# Loop through folders in the output and run the R code on each folder
for qdir in $SWS_output/*/; do
        qdir_name=`basename $qdir`
        echo $qdir_name
        export VARIABLENAME=$qdir
        echo -e 'source("Step_1_Setup.R") \n source("Step_2_Data.R") \n q()' | R --no-save --slave

done

然后R脚本如下所示:

qdir<-Sys.getenv("VARIABLENAME")
pathname<-qdir[1]

正如一些评论所指出的那样,这不是最佳实践,但这完全符合我的期望。谢谢!