r sweave

r - shiny using html



obtener el nombre de archivo y la ruta del archivo `source`d (6)

¿Cómo puede una source d o un archivo Sweave d descubrir su propia ruta?

Fondo:

Trabajo mucho con scripts .R o archivos .Rnw. Mis proyectos están organizados en una estructura de directorios, pero la ruta del directorio base del proyecto varía con frecuencia entre diferentes computadoras (por ejemplo, porque solo hago partes del análisis de datos para otra persona, y su estructura de directorios es diferente a la mía: tengo directorios base de proyectos ~ / Projects / StudentName / o ~ / Projects / Studentname / Projectname y la mayoría de los estudiantes que tienen solo un Proyecto lo tienen generalmente en ~ / Measurements / o ~ / DataAnalysis / o algo parecido, lo cual no funcionaría para mí).

Así que una línea como

setwd (my.own.path ())

sería increíblemente útil ya que permitiría garantizar que el directorio de trabajo sea la ruta base del proyecto, independientemente de dónde se encuentre realmente ese proyecto. Sin la necesidad de que el usuario piense en configurar el directorio de trabajo.

Permítanme aclarar: busco una solución que funcione presionando la source del editor / IDE o el método abreviado Sweave Keyboard del usuario irreflexivo.


A partir de las sugerencias de Seb de gsk3, he aquí una idea:

  • la combinación de nombre de usuario (inicio de sesión) e IP o el nombre de la computadora podrían usarse para seleccionar el directorio correcto.

Eso lleva a algo como:

setwd (switch (paste (Sys.info () [c ("user", "nodename")], collapse="."), user.laptop = "~/Messungen", user2.server = "~/Projekte/Projekt/", ))

Así que hay una solución automática, que

  • trabaja con source
  • trabaja con Sweave
  • Incluso funciona para sesiones interactivas en las que los comandos se envían línea por línea.

  • La combinación de user y nombre de nodename por supuesto, debe ser específica.

  • Sin embargo, los caminos deben ser editados a mano.

Mejoras bienvenidas!

Actualizar:

Gabor Grothendieck respondió lo siguiente a una pregunta relacionada sobre r-help hoy:

this.dir <- dirname(parent.frame(2)$ofile) setwd(this.dir)

que trabajará para la source .

Otra actualización: ahora hago la mayor parte del trabajo de análisis de datos en RStudio. Los proyectos de RStudio básicamente resuelven el problema: RStudio cambia el directorio de trabajo al directorio raíz del proyecto cada vez que cambio entre proyectos.

Por lo tanto, puedo poner el directorio del proyecto tan abajo en mi árbol de directorios como quiera (y los estudiantes también pueden poner su copia donde lo deseen) y sincronizar los archivos de datos y los scripts / .Rnw a través del control de versiones (utilizamos un servidor privado de git ). Los archivos de proyecto de RStudio se mantienen fuera del control de versión, es decir, .gitignore contiene .Rproj.user .

Obviamente, dentro del proyecto, la estructura del directorio debe estar sincronizada.


Esta respuesta funciona para la source y también para nvim-R . No tengo idea si funciona con knitr y cosas similares. Cualquier comentario apreciado.

Si tiene varios scripts source originan entre sí, es importante obtener el correcto. Es decir, la i más grande para la que sys.frame(i)$ofile .

get.full.path.to.this.sourced.script = function() { for(i in sys.nframe():1) { # Go through all the call frames, # in *reverse* order. x = sys.frame(i)$ofile if(!is.null(x)) # if $ofile exists, return(normalizePath(x)) # then return the full absolute path } }


No tengo una solución directa sobre cómo obtener el directorio del archivo en sí, pero si tiene un rango limitado de directorios y estructuras de directorios, probablemente pueda usar

if(file.exists("c:/somedir")==TRUE){setwd("c:/somedir")}

Podrías revisar el patrón del directorio en cuestión y luego configurar el directorio. ¿Te ayuda esto?


Puede usar sys.calls() para obtener el comando utilizado para sys.calls() el archivo. Luego necesitas un poco de truco con las expresiones regulares para obtener el nombre de ruta, teniendo en cuenta que la source("something/filename") podría haber usado la ruta absoluta o relativa. Este es un primer intento de juntar todas las piezas: intente insertar las siguientes líneas en la parte superior de un archivo fuente.

whereFrom=sys.calls()[[1]] # This should be an expression that looks something like # source("pathname/myfilename.R") whereFrom=as.character(whereFrom[2]) # get the pathname/filename whereFrom=paste(getwd(),whereFrom,sep="/") # prefix it with the current working directory pathnameIndex=gregexpr(".*/",whereFrom) # we want the string up to the final ''/'' pathnameLength=attr(pathnameIndex[[1]],"match.length") whereFrom=substr(whereFrom,1,pathnameLength-1) print(whereFrom) # or "setwd(whereFrom)" to set the working directory

No es muy robusto; por ejemplo, fallará en Windows con la source("pathname//filename") , y no he probado lo que sucede si tiene un archivo que se abastece de otro, pero es posible que pueda crear una solución. en la parte superior de esta.


Solo para su información, knitr setwd() al directorio del archivo de entrada cuando (y solo cuando) evalúe los fragmentos de código, es decir, si llama a knit(''path/to/input.Rnw'') , el directorio de trabajo cambiará temporalmente al path/to/ . Si desea conocer el directorio de entrada en fragmentos de código, actualmente puede llamar a una función no knitr:::input_dir() (Puedo exportarlo en el futuro).


Un problema adicional es que el directorio de trabajo es una variable global, que puede ser modificada por cualquier secuencia de comandos, por lo que si su secuencia de comandos llama a otra secuencia de comandos, deberá restablecer el wd. En RStudio uso Sesión -> Establecer directorio de trabajo -> A la ubicación del archivo de origen (lo sé, no es lo ideal), y luego mi script

wd = getwd () ... source ("mySubDir/myOtherScript.R", chdir=TRUE); setwd (wd) ... source ("anotherSubDir/anotherScript.R", chdir=TRUE); setwd (wd)

De esta manera uno puede mantener una pila de directorios de trabajo. Me encantaría ver esto implementado en el lenguaje mismo.