Jak mogę odczytać parametry wiersza poleceń ze skryptu R?

Mam skrypt R, dla którego chciałbym być w stanie podać kilka parametrów wiersza poleceń (zamiast wartości parametrów hardcode w samym kodzie). Skrypt działa w systemie Windows.

Nie mogę znaleźć informacji jak odczytać parametry podane w wierszu poleceń do mojego skryptu R. Zdziwiłbym się, gdyby nie można tego zrobić, więc może po prostu nie używam najlepszych słów kluczowych w mojej wyszukiwarce Google...

Jakieś wskazówki lub zalecenia?

Author: monch1962, 2010-01-28

10 answers

Odpowiedź Dirka tutaj jest wszystkim, czego potrzebujesz. Oto minimalny powtarzalny przykład.

Zrobiłem dwa pliki: exmpl.bat i exmpl.R.

  • exmpl.bat:

    set R_Script="C:\Program Files\R-3.0.2\bin\RScript.exe"
    %R_Script% exmpl.R 2010-01-28 example 100 > exmpl.batch 2>&1
    

    Alternatywnie, używając Rterm.exe:

    set R_TERM="C:\Program Files\R-3.0.2\bin\i386\Rterm.exe"
    %R_TERM% --no-restore --no-save --args 2010-01-28 example 100 < exmpl.R > exmpl.batch 2>&1
    
  • exmpl.R:

    options(echo=TRUE) # if you want see commands in output file
    args <- commandArgs(trailingOnly = TRUE)
    print(args)
    # trailingOnly=TRUE means that only your arguments are returned, check:
    # print(commandArgs(trailingOnly=FALSE))
    
    start_date <- as.Date(args[1])
    name <- args[2]
    n <- as.integer(args[3])
    rm(args)
    
    # Some computations:
    x <- rnorm(n)
    png(paste(name,".png",sep=""))
    plot(start_date+(1L:n), x)
    dev.off()
    
    summary(x)
    

Zapisz oba pliki w tym samym katalogu i uruchom exmpl.bat. W rezultacie otrzymasz:

  • example.png z jakąś fabułą
  • exmpl.batch with all that was done

Ty można również dodać zmienną środowiskową %R_Script%:

"C:\Program Files\R-3.0.2\bin\RScript.exe"

I używać go w skryptach wsadowych jako %R_Script% <filename.r> <arguments>

Różnice między RScript a Rterm:

  • Rscript ma prostszą składnię
  • Na x64 można wybrać architekturę, która będzie wyświetlana na x64 (zobacz R Installation and Administration, 2.6 Sub-architectures Po szczegóły)
  • Rscript potrzebuje options(echo=TRUE) wPlik R Jeśli chcesz zapisać polecenia do pliku wyjściowego
 194
Author: Marek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 14:18:54

Kilka punktów:

  1. Parametry wiersza poleceń to dostępne przez commandArgs(), więc zobacz help(commandArgs) dla przegląd.

  2. Możesz używać Rscript.exe na wszystkich platformach, w tym Windows. Będzie obsługiwać commandArgs(). littler Może być przeniesiony na Windows, ale teraz żyje tylko na OS X i Linux.

  3. Istnieją dwa dodatkowe pakiety CRAN -- getopt i optparse -- które zostały napisane dla wiersza poleceń parsowanie.

Edytuj w listopadzie 2015: pojawiły się nowe alternatywy i z całego serca Polecamdocopt .

 117
Author: Dirk Eddelbuettel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-01 13:17:37

Dodaj to do góry skryptu:

args<-commandArgs(TRUE)

Następnie można odnieść się do argumentów przekazywanych jako args[1], args[2] itd.

Następnie uruchom

Rscript myscript.R arg1 arg2 arg3

Jeśli Twoje args są ciągami znaków ze spacjami w nich, Zamknij w cudzysłowach.

 82
Author: Hrishi Mittal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-27 13:10:20

Spróbuj library (getopt)... jeśli chcesz, żeby było milej. Na przykład:

spec <- matrix(c(
        'in'     , 'i', 1, "character", "file from fastq-stats -x (required)",
        'gc'     , 'g', 1, "character", "input gc content file (optional)",
        'out'    , 'o', 1, "character", "output filename (optional)",
        'help'   , 'h', 0, "logical",   "this help"
),ncol=5,byrow=T)

opt = getopt(spec);

if (!is.null(opt$help) || is.null(opt$in)) {
    cat(paste(getopt(spec, usage=T),"\n"));
    q();
}
 12
Author: Erik Aronesty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-27 15:01:48

You need littler (wymawiane 'little r')

Dirk będzie za jakieś 15 minut do rozwinięcia;)

 8
Author: JD Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-28 00:48:54

Ponieważ optparse zostało wspomniane kilka razy w odpowiedziach i zapewnia kompleksowy zestaw do przetwarzania wiersza poleceń, oto krótki uproszczony przykład, jak możesz go użyć, zakładając, że plik wejściowy istnieje:

scenariusz.R:

library(optparse)

option_list <- list(
  make_option(c("-n", "--count_lines"), action="store_true", default=FALSE,
    help="Count the line numbers [default]"),
  make_option(c("-f", "--factor"), type="integer", default=3,
    help="Multiply output by this number [default %default]")
)

parser <- OptionParser(usage="%prog [options] file", option_list=option_list)

args <- parse_args(parser, positional_arguments = 1)
opt <- args$options
file <- args$args

if(opt$count_lines) {
  print(paste(length(readLines(file)) * opt$factor))
}

Podano dowolny plik blah.txt z 23 liniami.

W wierszu poleceń:

Rscript script.R -h wyjścia

Usage: script.R [options] file


Options:
        -n, --count_lines
                Count the line numbers [default]

        -f FACTOR, --factor=FACTOR
                Multiply output by this number [default 3]

        -h, --help
                Show this help message and exit

Rscript script.R -n blah.txt wyniki [1] "69"

Rscript script.R -n -f 5 blah.txt wyjścia [1] "115"

 7
Author: Megatron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-15 18:31:12

W bash możesz zbudować wiersz poleceń w następujący sposób:

$ z=10
$ echo $z
10
$ Rscript -e "args<-commandArgs(TRUE);x=args[1]:args[2];x;mean(x);sd(x)" 1 $z
 [1]  1  2  3  4  5  6  7  8  9 10
[1] 5.5
[1] 3.027650
$

Widać, że zmienna $z jest zastąpiona przez powłokę bash " 10 " i ta wartość jest pobierana przez commandArgs i przekazywana do args[2], A polecenie range x=1:10 wykonywane przez R pomyślnie, itd itd.

 5
Author: TTW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-27 21:18:53

FYI: istnieje funkcja args (), która pobiera argumenty funkcji R, nie mylić z wektorem argumentów o nazwie args

 3
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-10 02:43:18

Jeśli chcesz podać opcje z flagami, (jak -h, --help, -- number = 42, itd.) możesz użyć pakietu r optparse (zainspirowanego Pythonem): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf .

Przynajmniej tak rozumiem twoje pytanie, ponieważ znalazłem ten post, gdy szukałem odpowiednika Bash getopt, lub perl Getopt, lub python argparse i optparse.

 0
Author: TheBinturonGggh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-20 15:33:46

Po prostu zebrałem ładną strukturę danych i łańcuch przetwarzania, aby wygenerować takie zachowanie przełączania, bez bibliotek potrzebnych. Jestem pewien, że będzie to realizowane wiele razy, i natknąłem się na ten wątek szukając przykładów-pomyślałem, że się wkręcę.

Nie potrzebowałem nawet znaczników (jedynym znacznikiem tutaj jest tryb debugowania, tworzenie zmiennej, którą sprawdzam jako warunek uruchomienia funkcji downstream if (!exists(debug.mode)) {...} else {print(variables)}). FLAG checking lapply to samo co:

if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args) 

Gdzie args jest zmienną odczytywaną z argumentów linii poleceń (wektor znakowy, równoważny c('--debug','--help'), gdy na przykład je podasz)

Jest wielokrotnego użytku dla każdej innej flagi i unikasz powtarzania, bez bibliotek, więc bez zależności:

args <- commandArgs(TRUE)

flag.details <- list(
"debug" = list(
  def = "Print variables rather than executing function XYZ...",
  flag = "--debug",
  output = "debug.mode <- T"),
"help" = list(
  def = "Display flag definitions",
  flag = c("-h","--help"),
  output = "cat(help.prompt)") )

flag.conditions <- lapply(flag.details, function(x) {
  paste0(paste0('"',x$flag,'"'), sep = " %in% args", collapse = " || ")
})
flag.truth.table <- unlist(lapply(flag.conditions, function(x) {
  if (eval(parse(text = x))) {
    return(T)
  } else return(F)
}))

help.prompts <- lapply(names(flag.truth.table), function(x){
# joins 2-space-separatated flags with a tab-space to the flag description
  paste0(c(paste0(flag.details[x][[1]][['flag']], collapse="  "),
  flag.details[x][[1]][['def']]), collapse="\t")
} )

help.prompt <- paste(c(unlist(help.prompts),''),collapse="\n\n")

# The following lines handle the flags, running the corresponding 'output' entry in flag.details for any supplied
flag.output <- unlist(lapply(names(flag.truth.table), function(x){
  if (flag.truth.table[x]) return(flag.details[x][[1]][['output']])
}))
eval(parse(text = flag.output))

Zauważ, że w flag.details tutaj polecenia są przechowywane jako ciągi znaków, a następnie oceniane za pomocą eval(parse(text = '...')). Optparse jest oczywiście pożądany dla każdego poważnego skryptu, ale Kod o minimalnej funkcjonalności też jest dobry czasami.

Przykładowe wyjście:

$ Rscript check_mail.Rscript --help
--debug Print  variables rather than executing function XYZ...

-h  --help  Display flag definitions
 0
Author: Louis Maddox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-13 03:13:35