Как передать переменную bash в R скрипт - PullRequest
0 голосов
/ 26 июня 2019

У меня есть пара R-скриптов, которые обрабатывают данные в определенной входной папке. У меня есть несколько папок, на которых мне нужно запустить этот сценарий, поэтому я начал писать сценарий bash для циклического обхода этих папок и запуска этих сценариев R.

Я совсем не знаком с R (скрипт был написан предыдущим работником, и для меня это в основном черный ящик), и я неопытен в передаче переменных через скрипты, особенно с участием нескольких языков. Здесь также присутствует проблема, когда я вызываю источник ("$ 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 ]

1 голос
/ 26 июня 2019

Мой предыдущий ответ был неполным. Вот лучшее объяснение синтаксического анализа командной строки.

Довольно просто использовать функцию 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, и аргументы, которые файл будет импортировать, представляют собой три элемента, разделенных пробелом, runI, parmsC, xN. Вы можете добавить столько этих разделенных пробелами параметров, сколько захотите. Это на ваше усмотрение, как они называются, но требуется, чтобы они были разделены пробелами, и вокруг знаков равенства НЕТ ПРОСТРАНСТВА. Переменные символьных строк должны быть заключены в кавычки.

Моя привычка - именовать аргументы суффиксом «I», чтобы намекнуть, что это целое число, «C» - для символа, а «N» - для чисел с плавающей запятой.

В файле r-clargs-3.R включите некоторый код для чтения аргументов и их сортировки. Например, пример моего урока

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

Остальная часть работы заключается в сортировке аргументов, и это моя самая развитая строфа для сортировки аргументов (потому что она ищет суффиксы «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")
}

Это создаст переменные в сеансе R с именами paramsC, runI и xN.

Удобство этого подхода состоит в том, что один и тот же базовый код R может выполняться с 100 или 1000 с вариациями параметров команды. Хорошо для симуляции Монте-Карло и т. Д.

0 голосов
/ 26 июня 2019

Спасибо за все ответы, они были очень полезны. Я смог получить решение, которое работает. Вот мой законченный сценарий.

#!/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]

Как было отмечено в нескольких комментариях, это не лучшая практика, но она работала именно так, как я хотел. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...