web-dev-qa-db-fra.com

Obtenir le chemin du script actuel

Je voudrais définir le répertoire de travail sur le chemin du script actuel par programmation, mais je dois d’abord obtenir le chemin du script actuel.

Donc j'aimerais pouvoir faire:

current_path = ...retrieve the path of current script ...
setwd(current_path) 

Comme le menu RStudio le fait: RStudio set working directory

Jusqu'ici j'ai essayé:

initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.basename <- dirname(script.name)

script.name renvoie NULL

source("script.R", chdir = TRUE)

Retourne : Erreur dans le fichier (nom du fichier, "r", encoding = encoding): impossible d'ouvrir la connexion En outre: Message d'avertissement: Dans le fichier (nom du fichier, "r", encoding = encoding): impossible d'ouvrir le fichier '/script.R': aucun fichier ou répertoire de ce type

dirname(parent.frame(2)$ofile)

Retourne : Erreur dans le nom de répertoire (parent.frame (2) $ ofile): un argument de vecteur de caractère attendu ... car parent.frame. est nul

frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
PATH <- dirname(frame_files[[length(frame_files)]])

Retourne : Null car frame_files est une liste de 0

thisFile <- function() {
    cmdArgs <- commandArgs(trailingOnly = FALSE)
    needle <- "--file="
    match <- grep(needle, cmdArgs)
    if (length(match) > 0) {
        # Rscript
        return(normalizePath(sub(needle, "", cmdArgs[match])))
    } else {
        # 'source'd via R console
        return(normalizePath(sys.frames()[[1]]$ofile))
    }
}

Retourne : Erreur dans l'argument path.expand (path): argument 'path' invalide.

J'ai aussi vu toutes les réponses de ici , ici , ici et ici . Pas de joie.

Travailler avec RStudio 1.1.383

EDIT: Ce serait génial s'il n'y avait pas besoin d'une bibliothèque externe pour y parvenir.

23
Panos Kal.

Dans RStudio, vous pouvez obtenir le chemin du fichier actuellement affiché dans le volet source à l’aide de

rstudioapi::getSourceEditorContext()$path

Si vous ne voulez que le répertoire, utilisez

dirname(rstudioapi::getSourceEditorContext()$path)

Si vous voulez le nom du fichier qui a été exécuté par source(filename), c'est un peu plus difficile. Vous devez rechercher la variable srcfile quelque part dans la pile. La distance dépend de la façon dont vous écrivez les choses, mais il faut environ 4 pas en arrière: par exemple,

fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi

devrait imprimer la même chose sur les deux dernières lignes.

45
user2554330

Mise à jour août 2018

[~ # ~] tldr [~ # ~] : Le paquet ici vous aide à créer un chemin à partir du dossier racine du projet. peu importe où dans le dossier hiérarchique les scripts R ou les documents Rmd sont stockés.

Le package ici reste disponible sur CRAN. La version de développement a été déplacée vers github.com/r-lib/here . Les points mentionnés dans les sites cités ci-dessous restent valables.

Réponse précédente

Lisez le Ode au paquet ici :

Avez-vous: setwd () dans vos scripts? VEUILLEZ CESSER DE FAIRE CELA. Cela rend votre script très fragile, câblé à exactement un moment et un endroit. Dès que vous renommez ou déplacez des répertoires, cela casse. Ou peut-être vous obtenez un nouvel ordinateur? Ou peut-être que quelqu'un d'autre a besoin d'exécuter votre code?

[...]

Présentation classique du problème: difficulté à créer des chemins et/ou à définir un répertoire de travail dans des projets avec des sous-répertoires. Surtout si vous utilisez R Markdown et knitr, ce qui dérange beaucoup de gens avec son comportement par défaut de "répertoire de travail = répertoire où ce fichier vit". [...]

Installez le paquet ici :

install.packages("here")
library(here)
here()
here("construct","a","path")

Documentation de la fonction here():

Commençant par le répertoire de travail en cours lors du chargement du package, la hiérarchie des répertoires va ici jusqu'à trouver un répertoire satisfaisant à au moins l'une des conditions suivantes:

  • contient un fichier correspondant à [.] Rproj $ avec un contenu correspondant à ^ Version: dans la première ligne
  • [... autres options ...]
  • contient un répertoire .git

Une fois établi, le répertoire racine ne change pas pendant la session active de R. here () ajoute ensuite les arguments au répertoire racine.

La version de développement de le paquet ici est disponible sur github .

10
Paul Rougieux

Si vous exécutez un script Rscript via la ligne de commande, etc.

Rscript /path/to/script.R

La fonction ci-dessous assignera this_file à /path/to/script

library(tidyverse)
get_this_file <- function(){
    commandArgs() %>% 
       tibble::enframe(name=NULL) %>%
       tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
       dplyr::filter(key == "--file") %>%
       dplyr::pull(value)
}
this_file <- get_this_file()
3
Alexis Lucattini

Une autre option pour obtenir le chemin de script actuel est funr::get_script_path() et vous n'avez pas besoin d'exécuter votre script à l'aide de RStudio.

Mise à jour mars 2019

Basé sur Alexis Lucattini et les réponses de user2554330, pour le faire fonctionner à la fois en ligne de commande et RStudio. Résolution du message obsolète "as_tibble"

library(tidyverse)
getCurrentFileLocation <-  function()
{
    this_file <- commandArgs() %>% 
    tibble::enframe(name = NULL) %>%
    tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
    dplyr::filter(key == "--file") %>%
    dplyr::pull(value)
    if (length(this_file)==0)
    {
      this_file <- rstudioapi::getSourceEditorContext()$path
    }
    return(dirname(this_file))
}
2
Juan Bernabe

J'ai eu des problèmes avec tout cela parce qu'ils s'appuient sur des bibliothèques que je ne pouvais pas utiliser (à cause de Packrat) jusqu'à ce que je définisse le répertoire de travail (c'est pourquoi je devais commencer par obtenir le chemin).

Donc, voici une approche qui utilise uniquement la base R. (EDITED pour gérer Windows\caractères en plus des chemins d'accès/in)

args = commandArgs()

scriptName = args[substr(args,1,7) == '--file=']

if (length(scriptName) == 0) {
  scriptName <- rstudioapi::getSourceEditorContext()$path
} else {
  scriptName <- substr(scriptName, 8, nchar(scriptName))
}

pathName = substr(
  scriptName, 
  1, 
  nchar(scriptName) - nchar(strsplit(scriptName, '.*[/|\\]')[[1]][2])
)

1
Dov Rosenberg