Tengo un script llamado foo.R
que incluye otro script other.R
, que está en el mismo directorio:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Pero quiero R
encontrar eso other.R
sin importar el directorio de trabajo actual.
En otras palabras, foo.R
necesita 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"
.NULL
gelifico cuando esto se coloca en el servidor. R cuando uso brilloPuede utilizar la
commandArgs
funció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.name
siguiente comenzará con un'/'
. De lo contrario, debe ser relativo alcwd
y puede concatenar las dos rutas para obtener la ruta completa.Editar: parece que solo necesitarías lo
script.name
anterior 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.R
script 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
source
como 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
Rscript
ysource()
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.R
qué fuenteshelper.R
qué llamadasthisFile()
. Buscará el camino de enmain.R
lugar dehelper.R
. ¿Algún consejo aquí?Sin embargo, no me preguntes cómo funciona, porque he olvidado: /
fuente
sys.frames
devuelve 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 unofile
miembro.source("~/code/test.r")
,PATH
se establecerá en~/desktop
. Si solo lo evalúa en el nivel superior, devolverá NULL.x$ofile
está indefinido, por lo queframe_files
está 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
sourceDir
Estaba 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
scriptName
bibliotecaque 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
source
eso 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 eligepath
como 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_filename
funció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
thisScript
contiene 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--file
argumento 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.R
conociendo su ubicación de ruta, si puede cambiar su código para que siempre haga referencia a todassource
las rutas 'd desde un comúnroot
, estas pueden ser de gran ayuda:Dado
/app/deeply/nested/foo.R
/app/other.R
Esto 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