首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将bash变量传递给R脚本

如何将bash变量传递给R脚本
EN

Stack Overflow用户
提问于 2019-06-27 00:41:24
回答 2查看 3.2K关注 0票数 1

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

我对R一点也不熟悉(脚本是由以前的一个工作人员编写的,对我来说,它基本上是一个黑盒),而且我在通过脚本传递变量方面缺乏经验,特别是涉及多种语言。当我在这里调用$SWS_output (“$SWS_output/Step_1Setup.R”)时,还有一个问题--R并没有将我的source读取为一个变量,而是一个字符串。

下面是我的bash脚本:

代码语言:javascript
复制
#!/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),以告诉它要处理哪个文件夹。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-27 04:32:49

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

代码语言:javascript
复制
#!/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脚本如下所示:

代码语言:javascript
复制
qdir<-Sys.getenv("VARIABLENAME")
pathname<-qdir[1]

正如一些评论指出的那样,这不是最佳实践,但它完全按照我所希望的那样工作。谢谢!

票数 2
EN

Stack Overflow用户

发布于 2019-06-27 02:24:53

我之前的回答是不完整的。下面是更好地解释命令行解析的方法。

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

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

代码语言:javascript
复制
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中,包含一些代码来读取参数并对它们进行排序。例如,我的教程的示例

代码语言:javascript
复制
cli <- commandArgs(trailingOnly = TRUE) 
args <- strsplit(cli, "=", fixed = TRUE)

剩下的工作是对args进行排序,这是我用来对参数进行排序的最先进的一节(因为它查找后缀"I“、"N”、"C“和"L”(代表逻辑)),然后将输入强制转换为正确的变量类型(所有输入变量都是字符,除非我们使用as.integer()等进行强制):

代码语言:javascript
复制
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")
}

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

这种方法的便利之处在于,相同的基本R代码可以用100秒或1000秒的命令参数变化来运行。适用于蒙特卡罗模拟等。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56777529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档