command-line - r script from command line
¿Cómo puedo leer los parámetros de la línea de comandos de un script R? (10)
Agregue esto a la parte superior de su script:
args<-commandArgs(TRUE)
Luego puede referirse a los argumentos pasados como args[1]
, args[2]
etc.
Entonces corre
Rscript myscript.R arg1 arg2 arg3
Si sus argumentos son cadenas con espacios, escríbalos entre comillas dobles.
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 propio código). El script se ejecuta en Windows.
No puedo encontrar información sobre cómo leer los parámetros proporcionados en la línea de comandos en mi script R Me sorprendería que no se pudiera hacer, así que quizás no esté usando las mejores palabras clave en mi búsqueda de Google ...
¿Algún puntero o recomendación?
Algunos puntos:
Se puede acceder a los parámetros de la línea de comandos a través de
commandArgs()
, así que consulte lahelp(commandArgs)
para obtener una descripción general.Puede usar
Rscript.exe
en todas las plataformas, incluido Windows.commandArgs()
. littler podría ser portado a Windows pero ahora vive solo en OS X y Linux.Hay dos paquetes complementarios en CRAN, getopt y optparse , que fueron escritos para el análisis de la línea de comandos.
Edición en noviembre de 2015: han aparecido nuevas alternativas y recomiendo de todo corazón docopt .
Dado que optparse
se ha 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:
script.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 archivo arbitrario blah.txt
con 23 líneas.
En la línea de comando:
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
salidas [1] "69"
Rscript script.R -n -f 5 blah.txt
salidas [1] "115"
En bash, puedes construir una línea de comando 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
se sustituye por bash shell con "10" y este valor es recogido por commandArgs
y se alimenta a args[2]
, y el comando de rango x=1:10
ejecuta con éxito por R, etc. etc.
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
Prueba la biblioteca (getopt) ... si quieres que las cosas sean mejores. 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();
}
Si necesita especificar opciones con marcas, (como -h, --help, --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í es como entiendo tu pregunta, porque encontré esta publicación cuando buscaba un equivalente de bash getopt, perl Getopt, o python argparse y optparse.
Simplemente armé una buena estructura de datos y una cadena de procesamiento para generar este comportamiento de cambio, no se necesitan bibliotecas. Estoy seguro de que se habrá implementado varias veces, y me encontré con este hilo en busca de ejemplos, pensé que lo haría.
Ni siquiera necesité indicadores particularmente (el único indicador aquí es un modo de depuración, creando una variable que if (!exists(debug.mode)) {...} else {print(variables)})
como condición para iniciar una función en sentido descendente if (!exists(debug.mode)) {...} else {print(variables)})
. Las lapply
declaraciones de verificación de bandera producen lo mismo 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 comando (un vector de caracteres, equivalente a c(''--debug'',''--help'')
cuando los proporciona, por ejemplo)
Es reutilizable para cualquier otra marca y evita todas las repeticiones, y no las 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
necesitas littler (pronunciado ''little r'')
Dirk estará en unos 15 minutos para elaborar;)
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, utilizando
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 trama -
exmpl.batch
con todo lo que se hizo
También puede agregar una variable de entorno %R_Script%
:
"C:/Program Files/R-3.0.2/bin/RScript.exe"
y %R_Script% <filename.r> <arguments>
en sus scripts de proceso 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 (consulte Instalación y administración de R, Sub-arquitecturas 2.6 para más detalles) -
Rscript
necesitaoptions(echo=TRUE)
en el archivo .R si desea escribir los comandos en el archivo de salida