2010-08-10 25 views
55

¿Hay alguna manera de encontrar mediante programación la ruta de una secuencia de comandos R dentro de la secuencia de comandos?Obtención de la ruta de una secuencia de comandos R

Lo pregunto porque tengo varios scripts que usan RGtk2 y cargan una GUI de un archivo .glade.

En estos scripts estoy obligado a poner una instrucción setwd("path/to/the/script") al principio, de lo contrario, el archivo .glade (que está en el mismo directorio) no se encontrará.

Esto está bien, pero si muevo el script en un directorio diferente o a otra computadora, tengo que cambiar la ruta. Lo sé, no es un gran problema, pero sería bueno tener algo como:

setwd(getScriptPath())

Por lo tanto, existe una función similar?

+1

Esto sería particularmente útil en sesiones interactivas, como cuando se usa Rstudio. – Quantum7

+0

Parece que muchos de estos problemas de "ruta a archivo" ahora pueden resolverse con el paquete rprojroot: https://cran.r-project.org/web/packages/rprojroot/index.html. rprojroot se anuncia a sí mismo como "rprojroot: búsqueda de archivos en subdirectorios de proyectos". Una versión 'liviana' para uso interactivo es el paquete aquí: https://github.com/krlmlr/ aquí. – BarkleyBG

Respuesta

18

Uso source("yourfile.R", chdir = T)

+0

¡Oh, genial, no sabía de eso! ¡Gracias! – nico

+2

@nico Soy nuevo en R y quería hacer algo similar. Intenté esta solución pero recibo un error 'Error: '...' utilizado en un contexto incorrecto', ¿podría comentar cuál podría ser el problema? – Dronacharya

+1

@Dronacharya: ¡fácil! ¡'' 'Son solo un marcador de posición para el nombre de archivo! Ponga el nombre del archivo que desea incluir y está configurado – nico

4

Si envuelve su código en un paquete, siempre puede consultar partes del directorio del paquete.
Aquí se muestra un ejemplo del paquete RGtk2:

> system.file("ui", "demo.ui", package="RGtk2") 
[1] "C:/opt/R/library/RGtk2/ui/demo.ui" 
> 

Puede hacer lo mismo con un directorio inst/glade/ en sus fuentes que se convertirá en un directorio glade/ en el paquete instalado - y system.file() calculará la ruta para usted cuando está instalado, independientemente del SO.

+0

Gracias Dirk. Realmente tendré que comenzar y pensar en poner mis scripts en un paquete ... ¿De su respuesta supongo que no hay forma de hacerlo fuera de un paquete? – nico

+1

Puede cambiar el formato de otra cosa: establecer una variable de entorno y consultarla, o quitar el argumento que proporcionó el nombre del script a R, o ... pero ¿por qué no utilizar algo simple, probado, confiable y hecho para ese propósito? ;-) –

+0

¡Oh, por supuesto, me estaba preguntando si había alguna otra solución! ¡Gracias! – nico

6

explotar el implícito "--file" argumento de RSCRIPT

Al llamar a la secuencia de comandos con "RSCRIPT" (Rscript doc) la ruta completa de la secuencia de comandos se da como un parámetro del sistema . La siguiente función se aprovecha esta situación para sacar el directorio de script:

getScriptPath <- function(){ 
    cmd.args <- commandArgs() 
    m <- regexpr("(?<=^--file=).+", cmd.args, perl=TRUE) 
    script.dir <- dirname(regmatches(cmd.args, m)) 
    if(length(script.dir) == 0) stop("can't determine script dir: please call the script with Rscript") 
    if(length(script.dir) > 1) stop("can't determine script dir: more than one '--file' argument detected") 
    return(script.dir) 
} 
+1

Cuando ejecuto esto (en Ubuntu 15.10 con R 3.2.3), el argumento '--file' no contiene la ruta completa, por lo que el directorio de scripts devuelto está vacío: ' '' daniel @ computadora: ~/data $ Rscript Script.R /usr/lib/R/bin/exec/R --slave --no-restore --file = Script.R '' ' – daniel

+0

Funciona para mí (win7, R3.4). – mdag02

3

Esta respuesta funciona bien para mí:

script.dir <- dirname(sys.frame(1)$ofile) 

Nota: La escritura debe ser de origen con el fin de devolver camino correcto

encontré en: https://support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-

Pero todavía no entiendo qué es sys.frame (1) $ ofile. No encontré nada sobre eso en la documentación de R. Alguien puede explicarlo?

+0

sí. sin origen, se obtiene el siguiente error: Error en dirname (parent.frame (2) $ ofile): se espera un argumento de vector de caracteres –

+2

Como tal, esto no funciona para el script principal de R. –

33

Esto funciona para mí:

getSrcDirectory(function(x) {x}) 

Esto define una función anónima (que no hace nada) dentro de la secuencia de comandos y, a continuación, determina el directorio de origen de esa función, que es el directorio en el que el guión es.

+21

Esto no funciona para mí en Linux R 3.2.4. La salida está en blanco. – biocyberman

+1

Funciona para mí en 3.3.2. @biocyberman: ¿estás llamando esto desde la consola? Porque vuelve allí en blanco para mí. Si proviene de un script, ¿lo está imprimiendo? (De manera similar, funciona cuando se genera desde Rstudio, no se bota cuando se ejecuta el código). – naught101

+1

Funciona en 3.3.2 en OSX 10.11.6 PERO solo cuando se compra el script en RStudio, como escribió @ naught101. Devuelve en blanco cuando se llama en la consola o cuando CMD-Devuelve la línea en la ventana de script. – mattek

22

Para rstudio solamente:

setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) 

Esto funciona cuando Run Ning o Fuente ing su archivo.

+0

no funcionó para mí. Tuve que usar: setwd (dirname (rstudioapi :: callFun ("getActiveDocumentContext") $ path)) de lo contrario: gran solución - gracias – MarkusN

+1

Error en loadNamespace (nombre): no hay ningún paquete llamado 'rstudioapi' –

+1

@HillarySanders ¿Lo hiciste? install.packages ("rstudioapi") '? –

1
#' current script dir 
#' @param 
#' @return 
#' @examples 
#' works with source() or in RStudio Run selection 
#' @export 
z.csd <- function() { 
    # http://stackoverflow.com/questions/1815606/rscript-determine-path-of-the-executing-script 
    # must work with source() 
    if (!is.null(res <- .thisfile_source())) res 
    else if (!is.null(res <- .thisfile_rscript())) dirname(res) 
    # http://stackoverflow.com/a/35842176/2292993 
    # RStudio only, can work without source() 
    else dirname(rstudioapi::getActiveDocumentContext()$path) 
} 
# Helper functions 
.thisfile_source <- function() { 
    for (i in -(1:sys.nframe())) { 
     if (identical(sys.function(i), base::source)) 
      return (normalizePath(sys.frame(i)$ofile)) 
    } 

    NULL 
} 
.thisfile_rscript <- function() { 
    cmdArgs <- commandArgs(trailingOnly = FALSE) 
    cmdArgsTrailing <- commandArgs(trailingOnly = TRUE) 
    cmdArgs <- cmdArgs[seq.int(from=1, length.out=length(cmdArgs) - length(cmdArgsTrailing))] 
    res <- gsub("^(?:--file=(.*)|.*)$", "\\1", cmdArgs) 

    # If multiple --file arguments are given, R uses the last one 
    res <- tail(res[res != ""], 1) 
    if (length(res) > 0) 
     return (res) 

    NULL 
} 
0

¿Qué le parece usar el sistema y comandos de shell? Con el de Windows, creo que al abrir el script en RStudio establece el directorio del shell actual en el directorio del script. Es posible que tenga que agregar cd C: \ e.g o cualquier disco que desee buscar (por ejemplo, shell ('dir C: \\ * file_name/s', intern = TRUE) - \\ para escapar del carácter de escape). Solo funcionará para archivos con nombres exclusivos a menos que especifique subdirectorios (para Linux comencé a buscar desde /). En cualquier caso, si usted sabe cómo encontrar algo en el intérprete de comandos, esto proporciona un diseño para encontrarlo dentro de R y devolver el directorio. Debería funcionar si está comprando o ejecutando el script, pero no he explorado completamente los posibles errores.

#Get operating system 
OS<-Sys.info() 
win<-length(grep("Windows",OS)) 
lin<-length(grep("Linux",OS)) 

#Find path of data directory 
#Linux Bash Commands 
if(lin==1){ 
    file_path<-system("find/-name 'file_name'", intern = TRUE) 
    data_directory<-gsub('/file_name',"",file_path) 
} 
#Windows Command Prompt Commands 
if(win==1){ 
    file_path<-shell('dir file_name /s', intern = TRUE) 
    file_path<-file_path[4] 
    file_path<-gsub(" Directory of ","",file_path) 
    filepath<-gsub("\\\\","/",file_path) 
    data_directory<-file_path 
} 

#Change working directory to location of data and sources 
setwd(data_directory) 
Cuestiones relacionadas