¿Cómo puedo leer los parámetros de la línea de comandos de un script R?
Tengo un script R para el que me gustaría poder suministrar varios parámetros de línea de comandos (en lugar de valores de parámetros de código duro en el código mismo). El script se ejecuta en Windows.
No puedo encontrar información sobre cómo leer los parámetros suministrados en la línea de comandos en mi script R. Me sorprendería si no se puede hacer, así que tal vez no estoy usando las mejores palabras clave en mi búsqueda en Google...
¿Algún consejo o recomendación?
10 answers
La respuesta de Dirk aquí es todo lo que necesitas. Aquí hay un ejemplo reproducible mínimo.
Hice dos archivos: exmpl.bat
y 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
Alternativamente, usando
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)
Guarde ambos archivos en el mismo directorio e inicie exmpl.bat
. En el resultado obtendrás:
-
example.png
con alguna parcela -
exmpl.batch
con todo lo que se hizo
Usted también podría agregar una variable de entorno %R_Script%
:
"C:\Program Files\R-3.0.2\bin\RScript.exe"
Y úselo en sus scripts por lotes como %R_Script% <filename.r> <arguments>
Diferencias entre RScript
y Rterm
:
-
Rscript
tiene una sintaxis más simple -
Rscript
elige automáticamente la arquitectura en x64 (ver R Instalación y Administración, subarquitectura 2.6 para más detalles) -
Rscript
necesitaoptions(echo=TRUE)
en el.Archivo R si desea escribir los comandos en el archivo de salida
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-02 14:18:54
Algunos puntos:
Los parámetros de la línea de comandos son accesible a través de
commandArgs()
, so véasehelp(commandArgs)
para una descripción.Puede usar
Rscript.exe
en todas las plataformas, incluyendo Windows. SoportarácommandArgs()
. littler podría ser portado a Windows, pero vive ahora solo en OS X y Linux.Hay dos paquetes para agregar en CRAN -- getopt y optparse -- que fueron escritas para la línea de comandos analizar.
Editar en noviembre de 2015: Han aparecido nuevas alternativas y Yo de todo corazón recomiendo docopt.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-01 13:17:37
Añade esto al principio de tu script:
args<-commandArgs(TRUE)
Entonces puede referirse a los argumentos pasados como args[1]
, args[2]
etc.
Luego ejecuta
Rscript myscript.R arg1 arg2 arg3
Si sus args son cadenas con espacios en ellas, encierre entre comillas dobles.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-27 13:10:20
Prueba la biblioteca(getopt) ... si quieres que las cosas sean más agradables. Por ejemplo:
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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-27 15:01:48
Necesitas más pequeño (pronunciado 'pequeña r')
Dirk estará en unos 15 minutos para elaborar;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-28 00:48:54
Dado que optparse
ha sido mencionado un par de veces en las respuestas, y proporciona un kit completo para el procesamiento de la línea de comandos, aquí hay un breve ejemplo simplificado de cómo puede usarlo, asumiendo que el archivo de entrada existe:
guión.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))
}
Dado un fichero arbitrario blah.txt
con 23 líneas.
En la línea de comandos:
Rscript script.R -h
salidas
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
productos [1] "69"
Rscript script.R -n -f 5 blah.txt
salidas [1] "115"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-15 18:31:12
En bash, puedes construir una línea de comandos como la siguiente:
$ 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
$
Puede ver que la variable $z
es sustituida por bash shell con "10" y este valor es recogido por commandArgs
y alimentado en args[2]
, y el comando range x=1:10
ejecutado por R con éxito, etc etc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 21:18:53
Para su información: hay una función args (), que recupera los argumentos de las funciones R, que no debe confundirse con un vector de argumentos llamado args
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 02:43:18
Si necesita especificar opciones con banderas, (como-h, help help, number number=42, etc.) puede usar el paquete R optparse (inspirado en Python): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf .
Al menos así entiendo tu pregunta, porque encontré este post cuando buscaba un equivalente de bash getopt, o perl Getopt, o python argparse y optparse.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-20 15:33:46
Acabo de armar una buena estructura de datos y cadena de procesamiento para generar este comportamiento de conmutación, no se necesitan bibliotecas. Estoy seguro de que se ha implementado en numerosas ocasiones, y me encontré con este hilo en busca de ejemplos - pensé que me gustaría contribuir.
Ni siquiera necesitaba banderas (la única bandera aquí es un modo de depuración, creando una variable que compruebo como condición para iniciar una función descendente if (!exists(debug.mode)) {...} else {print(variables)})
. El flag checking lapply
de abajo produce la igual que:
if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args)
Donde args
es la variable leída desde los argumentos de la línea de comandos (un vector de caracteres, equivalente a c('--debug','--help')
cuando proporciona estos, por ejemplo)
Es reutilizable para cualquier otra bandera y se evita toda la repetición, y no hay bibliotecas por lo que no hay dependencias:
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))
Tenga en cuenta que en flag.details
aquí los comandos se almacenan como cadenas, luego se evalúan con eval(parse(text = '...'))
. Optparse es obviamente deseable para cualquier script serio, pero el código de funcionalidad mínima también es bueno a veces.
Salida de muestra:
$ Rscript check_mail.Rscript --help --debug Print variables rather than executing function XYZ... -h --help Display flag definitions
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-13 03:13:35