¿Cómo puedo leer los parámetros de línea de comandos de un script R?

Tengo un script R para el cual me gustaría poder proporcionar varios parámetros de línea de comandos (en lugar de valores de parámetro de código duro en el código mismo). La secuencia de comandos 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 si no se puede hacer, así que tal vez no estoy utilizando las mejores palabras clave en mi búsqueda de Google …

¿Alguna sugerencia o sugerencia?

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-restre --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 ttwig
  • exmpl.batch con todo lo que se hizo

También podría agregar una variable de entorno %R_Script% :

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

y utilícelo en sus scripts por lotes como %R_Script%

Diferencias entre RScript y Rterm :

  • Rscript tiene una syntax más simple
  • Rscript elige automáticamente la architecture en x64 (ver R Subinstalaciones e instalación y administración para más detalles)
  • Rscript necesita options(echo=TRUE) en el archivo .R si desea escribir los comandos en el archivo de salida

Algunos puntos:

  1. Los parámetros de la línea de comando son accesibles a través de commandArgs() , por lo tanto, consulte la help(commandArgs) para obtener una descripción general.

  2. Puede usar Rscript.exe en todas las plataformas, incluido Windows. commandArgs() . Littler podría ser portado a Windows, pero vive ahora solo en OS X y Linux.

  3. Hay dos paquetes complementarios en CRAN – getopt y optparse – que fueron escritos para el análisis de línea de comandos.

Editar en noviembre de 2015: han aparecido nuevas alternativas y recomiendo docopt de todo corazón .

Agregue esto a la parte superior de su secuencia de comandos:

 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 args son cadenas con espacios en ellas, enciérrelas entre comillas dobles.

Pruebe la biblioteca (getopt) … si quiere 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(); } 

necesitas más pequeño (pronunciado ‘pequeño r’)

Dirk estará listo en unos 15 minutos para elaborar;)

Como optparse se ha mencionado un par de veces en las respuestas, y proporciona un kit completo para el procesamiento de línea de comandos, aquí hay un breve ejemplo simplificado de cómo puede usarlo, suponiendo que exista el archivo de entrada:

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 produce [1] "69"

Rscript script.R -n -f 5 blah.txt [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 es sustituida por bash shell con "10" y este valor es recogido por commandArgs y alimentado a args[2] , y el comando de rango x=1:10 ejecutado por R con éxito, etc., etc.

FYI: hay una función args (), que recupera los argumentos de las funciones R, que no debe confundirse con un vector de argumentos llamado args

Si necesita especificar opciones con flags, (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í entiendo tu pregunta, porque encontré esta publicación cuando busqué un equivalente de bash getopt, o perl Getopt, o python argparse y optparse.

Simplemente armé una buena estructura de datos y una cadena de procesamiento para generar este comportamiento de conmutación, no se necesitan bibliotecas. Estoy seguro de que habrá sido implementado muchas veces, y encontré este hilo buscando ejemplos, pensé que lo haría.

Ni siquiera necesitaba banderas en particular (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 comenzar una función en sentido descendente if (!exists(debug.mode)) {...} else {print(variables)}) . La bandera que verifica lapply declaraciones de lapply continuación produce 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 se suministran estos por ejemplo)

Es reutilizable para cualquier otro marcador y evita toda 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.

Muestra de salida:

  $ Rscript check_mail.Rscript --help
 --debug Imprimir variables en lugar de ejecutar la función XYZ ...

 -h --help Mostrar definiciones de indicador