Tengo un script llamado foo.Rque incluye otro script other.R, que está en el mismo directorio:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Pero quiero Rencontrar eso other.Rsin importar el directorio de trabajo actual.
En otras palabras, foo.Rnecesita conocer su propio camino. ¿Cómo puedo hacer eso?

Respuestas:
Aquí hay una solución simple para el problema. Este comando:
devuelve la ruta del archivo de script actual. Funciona después de que se guardó el guión.
fuente
dirname(sys.frame(1)$ofile)directamente desde Rstudio. Funciona bien cuando el script se ejecuta usando source ("other.R"), ydirname(sys.frame(1)$ofile)está dentro"other.R".NULLgelifico cuando esto se coloca en el servidor. R cuando uso brilloPuede utilizar la
commandArgsfunción para obtener todas las opciones que Rscript pasó al intérprete R real y buscarlas.--file=. Si su script se inició desde la ruta o si se inició con una ruta completa, loscript.namesiguiente comenzará con un'/'. De lo contrario, debe ser relativo alcwdy puede concatenar las dos rutas para obtener la ruta completa.Editar: parece que solo necesitarías lo
script.nameanterior y quitar el componente final de la ruta. Eliminé lacwd()muestra innecesaria, limpié el script principal y publiqué miother.R. Simplemente guarde este script y elother.Rscript en el mismo directoriochmod +x, y ejecute el script principal.main.R :
otro.R :
salida :
Esto es lo que creo que Dehmann está buscando.
fuente
sourcecomo pensé que quería el OP, pero tal vez leí mal su requisito. Pero no puedo deshacerme :( ¡Lo siento!other.name <- file.path(script.basename, "other.R")commandArgs(trailingOnly = FALSE)dentro de server.R en una aplicación brillante, me sale[1] "RStudio" "--interactive". No hay información sobre el directorio desde el que se llamó.No pude lograr que la solución Suppressingfire funcionara cuando 'fuente' desde la consola R.
No pude conseguir que la solución de Hadley funcionara al usar Rscript.
¿Lo mejor de ambos mundos?
fuente
Rscriptysource()dentro de R. Sugeriría hacerlonormalizePath()en ambas versiones, de modo que proporcione la ruta completa en ambos casos.library(base)me llevó un tiempo entender eso jajajasource(file.path(dirname(thisFile()), "other.R"))enfoo.R. Esto funciona para mi.main.Rqué fuenteshelper.Rqué llamadasthisFile(). Buscará el camino de enmain.Rlugar dehelper.R. ¿Algún consejo aquí?Sin embargo, no me preguntes cómo funciona, porque he olvidado: /
fuente
sys.framesdevuelve los entornos de la pila de llamadas, por lo que solo tiene sentido cuando se llama desde una función. Pruebe, por ejemplo,foo <- function() {bar <- function() print(sys.frames()); bar()}; foo(). Sin embargo, no puedo entender el código de @ hadley porque los entornos no tienen unofilemiembro.source("~/code/test.r"),PATHse establecerá en~/desktop. Si solo lo evalúa en el nivel superior, devolverá NULL.x$ofileestá indefinido, por lo queframe_filesestá vacío.Esto funciona para mi
fuente
Error: RStudio not running.""en mi casoLa respuesta de rakensi de Getting path of a R script es la IMHO más correcta y realmente brillante. Sin embargo, sigue siendo un truco que incorpora una función ficticia. Lo estoy citando aquí, para que otros lo encuentren más fácilmente.
Esto proporciona el directorio del archivo donde se colocó la instrucción (donde se define la función ficticia). Luego se puede usar para establecer el directorio de trabajo y usar rutas relativas, por ejemplo
o para crear caminos absolutos
fuente
sourceDirEstaba en blanco.character(0). Sugerencias?Mi todo en uno! (--01 / 09/2019 actualizado para tratar con RStudio Console)
fuente
Una variante reducida de la respuesta de Supressingfire:
fuente
Esto funciona para mi. Simplemente lo saca de los argumentos de la línea de comando, elimina el texto no deseado, hace un nombre de directorio y finalmente obtiene la ruta completa de eso:
fuente
He terminado y extendido las respuestas a esta pregunta en una nueva función
thisfile()en rprojroot . También funciona para tejer conknitr.fuente
Me gustó la solución de steamer25, ya que parece la más robusta para mis propósitos. Sin embargo, al depurar en RStudio (en Windows), la ruta no se configuraría correctamente. La razón es que si se establece un punto de interrupción en RStudio, el origen del archivo utiliza un comando alternativo de "fuente de depuración" que establece la ruta del script de forma un poco diferente. Aquí está la versión final que estoy usando actualmente que explica este comportamiento alternativo dentro de RStudio al depurar:
fuente
Intenté casi todo desde esta pregunta, Obtener la ruta de un script R , Obtener la ruta del script actual , Buscar la ubicación del archivo .R actual y el comando R para configurar el directorio de trabajo en la ubicación del archivo fuente en Rstudio , pero al final me encontré manualmente hojeando la tabla CRAN y encontrado
scriptNamebibliotecaque proporciona la
current_filename()función, que devuelve la ruta completa adecuada del script cuando se obtiene en RStudio y también cuando se invoca a través de R o RScript ejecutable.fuente
Package ‘scriptName’ was removed from the CRAN repository.- ¿ahora que? : oTambién tuve este problema, y ninguna de las soluciones anteriores funcionó para mí. Quizás con el
sourceeso o cosas así, pero no estaba lo suficientemente claro.Encontré esta solución, para mí elegante:
Lo importante es
fileSnapshot()que le brinda mucha información sobre un archivo. Devuelve una lista de 8 elementos. Cuando eligepathcomo elemento de la lista, la ruta se devuelve con un\\separador, por lo que el resto del código es solo para cambiar eso.Espero que esto ayude.
fuente
Puede ajustar el script r en un script bash y recuperar la ruta del script como una variable bash de la siguiente manera:
fuente
Me gusta este enfoque:
fuente
Acabo de resolver esto yo mismo. Para garantizar la portabilidad de su script, comience siempre con:
Funciona porque "." se traduce como el comando Unix $ PWD. Asignar esta cadena a un objeto de caracteres le permite insertar ese objeto de caracteres en setwd () y Presto su código siempre se ejecutará con su directorio actual como directorio de trabajo, sin importar en qué máquina se encuentre o en qué parte de la estructura de archivos se encuentre. situado. (Bonificación adicional: el objeto wd se puede usar con file.path () (es decir, file.path (wd, "output_directory") para permitir la creación de un directorio de salida estándar independientemente de la ruta del archivo que conduce a su directorio nombrado. Esto requiere que cree el nuevo directorio antes de hacer referencia a él de esta manera, pero eso también se puede ayudar con el objeto wd.
Alternativamente, el siguiente código realiza exactamente lo mismo:
o, si no necesita la ruta del archivo en un objeto, simplemente puede:
fuente
Tenga en cuenta que el paquete getopt proporciona la
get_Rscript_filenamefunción, que solo usa la misma solución presentada aquí, pero ya está escrita para usted en un módulo R estándar, por lo que no tiene que copiar y pegar la función "get script path" en cada script usted escribe.fuente
R -e "library(getopt); testscript.R"Rscript.Consulte
findSourceTraceback()el paquete R.utils , quefuente
Tuve problemas con las implementaciones anteriores, ya que mi script se maneja desde un directorio con enlaces simbólicos, o al menos por eso creo que las soluciones anteriores no funcionaron para mí. En la línea de la respuesta de @ennuikiller, envolví mi Rscript en bash. Establezco la variable de ruta usando
pwd -P, que resuelve las estructuras de directorios enlazados. Luego pase el camino hacia el Rscript.Bash.sh
foo.R
fuente
Usaría una variante del enfoque de @ steamer25. El punto es que prefiero obtener el último script de origen incluso cuando mi sesión se inició a través de Rscript. El siguiente fragmento, cuando se incluye en un archivo, proporcionará una variable que
thisScriptcontiene la ruta normalizada del script. Confieso el uso (ab) de la fuente, por lo que a veces invoco Rscript y el script proporcionado en el--fileargumento genera otro script que genera otro ... Algún día invertiré para hacer que mi código desordenado se convierta en un paquete.fuente
El 99% de los casos que podrías usar simplemente:
No funcionará para las llamadas de locos en el que el guión no es el primer argumento, es decir,
source(some args, file="myscript"). Use @ hadley en estos casos elegantes.fuente
El enfoque de Steamer25 funciona, pero solo si no hay espacios en blanco en el camino. En macOS, al menos,
cmdArgs[match]devuelve algo así como/base/some~+~dir~+~with~+~whitespace/para/base/some\ dir\ with\ whitespace/.Trabajé alrededor de esto reemplazando el "~ + ~" con un espacio en blanco simple antes de devolverlo.
Obviamente, aún puede extender el bloque else como lo hizo aprstar.
fuente
Si en lugar de la secuencia de comandos,
foo.Rconociendo su ubicación de ruta, si puede cambiar su código para que siempre haga referencia a todassourcelas rutas 'd desde un comúnroot, estas pueden ser de gran ayuda:Dado
/app/deeply/nested/foo.R/app/other.REsto funcionará
Consulte https://rprojroot.r-lib.org/ para saber cómo definir las raíces del proyecto.
fuente
fuente
¡Es increíble que no haya una estructura tipo '$ 0' en R! Puede hacerlo con una llamada system () a un script bash escrito en R:
Luego solo divide el nombre scriptpath.sh para otro.
fuente
readLink: illegal option -- e usage: readLink [-FlLnqrsx] [-f format] [-t timefmt] [file ...]Al observar la pila de llamadas, podemos obtener la ruta de archivo de cada script que se está ejecutando, los dos más útiles probablemente serán el script que se está ejecutando actualmente o el primer script que se obtendrá (entrada).
fuente