J'ai un script appelé foo.R
qui inclut un autre script other.R
, qui se trouve dans le même répertoire:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Mais je veux R
trouver que other.R
quel que soit le répertoire de travail actuel.
En d'autres termes, foo.R
doit connaître son propre chemin. Comment puis je faire ça?
Réponses:
Ici, il existe une solution simple au problème. Cette commande:
renvoie le chemin du fichier de script actuel. Cela fonctionne après que le script a été enregistré.
la source
dirname(sys.frame(1)$ofile)
directement à partir de Rstudio. Cela fonctionne bien lorsque le script est exécuté à l'aide de source ("other.R"), etdirname(sys.frame(1)$ofile)
est à l'intérieur"other.R"
.NULL
gélifie lorsque cela est placé dans le serveur.R lors de l'utilisation de brillantVous pouvez utiliser la
commandArgs
fonction pour obtenir toutes les options passées par Rscript à l'interpréteur R réel et les rechercher--file=
. Si votre script a été lancé à partir du chemin d'accès ou s'il a été lancé avec un chemin d'accès complet, ce quiscript.name
suit commencera par un'/'
. Sinon, il doit être relatif à lacwd
et vous pouvez concaténer les deux chemins pour obtenir le chemin complet.Modifier: il semble que vous n'ayez besoin que de ce qui
script.name
précède et que vous supprimiez le dernier composant du chemin. J'ai supprimé l'cwd()
échantillon inutile , nettoyé le script principal et publié monother.R
. Enregistrez simplement ce script et leother.R
script dans le même répertoire,chmod +x
eux, et exécutez le script principal.main.R :
autre.R :
sortie :
C'est ce que je crois que dehmann recherche.
la source
source
car je pensais que l'OP le voulait - mais peut-être que j'ai mal lu son exigence. Mais je ne peux pas dé-downmod :( Désolé!other.name <- file.path(script.basename, "other.R")
commandArgs(trailingOnly = FALSE)
intérieur de server.R dans une application brillante, j'obtiens[1] "RStudio" "--interactive"
. Aucune information sur le répertoire d'où il a été appelé.Je n'ai pas pu faire fonctionner la solution de Suppressingfire lors de la 'source' à partir de la console R.
Je n'ai pas pu faire fonctionner la solution de hadley lors de l'utilisation de Rscript.
Le meilleur des deux mondes?
la source
Rscript
etsource()
au sein de R. Je suggère de le fairenormalizePath()
sur les deux versions, afin qu'il donne le chemin complet dans les deux cas.library(base)
il m'a fallu un certain temps pour comprendre cela lolsource(file.path(dirname(thisFile()), "other.R"))
enfoo.R
. Cela fonctionne pour moi.main.R
quelles sourceshelper.R
quels appelsthisFile()
. Il récupérera le chemin demain.R
au lieu dehelper.R
. Des conseils ici?Ne me demandez pas comment ça marche, car j'ai oublié: /
la source
sys.frames
renvoie les environnements de la pile d'appels, donc cela n'a vraiment de sens que lorsqu'il est appelé à partir d'une fonction. Essayez, par exemple,foo <- function() {bar <- function() print(sys.frames()); bar()}; foo()
. Je ne peux pas comprendre le code de @ hadley car les environnements n'ont pas deofile
membre.source("~/code/test.r")
,PATH
sera réglé sur~/desktop
. Si vous l'évaluez simplement au niveau supérieur, il renverra NULL.x$ofile
n'est pas défini, ilframe_files
est donc vide.Ça marche pour moi
la source
Error: RStudio not running
.""
dans mon casLa réponse de rakensi de Obtenir le chemin d'un script R est à mon humble avis le plus correct et le plus brillant. Pourtant, c'est toujours un hack intégrant une fonction factice. Je le cite ici, afin qu'il soit plus facile à trouver par les autres.
Cela donne le répertoire du fichier où l'instruction a été placée (où la fonction factice est définie). Il peut ensuite être utilisé pour définir le répertoire de travail et utiliser des chemins relatifs, par exemple
ou pour créer des chemins absolus
la source
sourceDir
était vide.character(0)
. Suggestions?Mon tout en un! (--01 / 09/2019 mis à jour pour gérer la console RStudio)
la source
Une variante allégée de la réponse de Supressingfire:
la source
Cela fonctionne pour moi. Il suffit de le sortir des arguments de la ligne de commande, de supprimer le texte indésirable, de faire un nom de répertoire et d'obtenir enfin le chemin complet à partir de cela:
la source
J'ai terminé et étendu les réponses à cette question dans une nouvelle fonction
thisfile()
dans rprojroot . Fonctionne également pour tricoter avecknitr
.la source
J'ai aimé la solution de steamer25 car elle semble la plus robuste pour mes besoins. Cependant, lors du débogage dans RStudio (dans Windows), le chemin ne serait pas correctement défini. La raison étant que si un point d'arrêt est défini dans RStudio, le sourcing du fichier utilise une autre commande "debug source" qui définit le chemin du script un peu différemment. Voici la version finale que j'utilise actuellement et qui explique ce comportement alternatif dans RStudio lors du débogage:
la source
J'ai essayé presque tout de cette question, obtenir le chemin d'un script R , obtenir le chemin du script actuel , trouver l'emplacement du fichier .R actuel et la commande R pour définir le répertoire de travail à l'emplacement du fichier source dans Rstudio , mais à la fin je me suis retrouvé manuellement parcourant la table CRAN et trouvé
scriptName
bibliothèquequi fournit une
current_filename()
fonction, qui renvoie le chemin d'accès complet du script lors de l'approvisionnement dans RStudio et également lors de l'appel via un exécutable R ou RScript.la source
Package ‘scriptName’ was removed from the CRAN repository.
- et maintenant? : oJ'ai également eu ce problème et aucune des solutions ci-dessus n'a fonctionné pour moi. Peut-être avec le
source
ou des choses comme ça, mais ce n'était pas assez clair.J'ai trouvé cette solution, élégante pour moi:
L'important est
fileSnapshot()
que cela vous donne beaucoup d'informations sur un fichier. Il renvoie une liste de 8 éléments. Lorsque vous choisissezpath
comme élément de liste, le chemin d'accès est renvoyé avec\\
comme séparateur, donc le reste du code est juste pour changer cela.J'espère que ça aide.
la source
Vous pouvez encapsuler le script r dans un script bash et récupérer le chemin du script en tant que variable bash comme ceci:
la source
J'aime cette approche:
la source
Je viens de résoudre ça moi-même. Pour garantir la portabilité de votre script, commencez toujours par:
Cela fonctionne parce que "." traduit comme la commande Unix $ PWD. L'affectation de cette chaîne à un objet caractère vous permet ensuite d'insérer cet objet caractère dans setwd () et Presto votre code s'exécutera toujours avec son répertoire actuel comme répertoire de travail, quelle que soit la machine sur laquelle il se trouve ou où dans la structure de fichiers où il se trouve. situé. (Bonus supplémentaire: l'objet wd peut être utilisé avec file.path () (c'est-à-dire file.path (wd, "output_directory") pour permettre la création d'un répertoire de sortie standard quel que soit le chemin de fichier menant à votre répertoire nommé. Cela vous oblige à créer le nouveau répertoire avant de le référencer de cette façon, mais cela aussi peut être aidé avec l'objet wd.
Alternativement, le code suivant effectue exactement la même chose:
ou, si vous n'avez pas besoin du chemin du fichier dans un objet, vous pouvez simplement:
la source
Notez que le package getopt fournit la
get_Rscript_filename
fonction, qui utilise simplement la même solution présentée ici, mais est déjà écrite pour vous dans un module R standard, vous n'avez donc pas à copier et coller la fonction "get script path" dans chaque script vous écrivez.la source
R -e "library(getopt); testscript.R"
Rscript
.Voir
findSourceTraceback()
le package R.utils , quila source
J'ai eu des problèmes avec les implémentations ci-dessus car mon script est exploité à partir d'un répertoire de liens symboliques, ou du moins c'est pourquoi je pense que les solutions ci-dessus n'ont pas fonctionné pour moi. Dans le sens de la réponse de @ ennuikiller, j'ai enveloppé mon Rscript dans bash. J'ai défini la variable de chemin à l'aide de
pwd -P
, qui résout les structures de répertoires à liens symboliques. Passez ensuite le chemin dans le Rscript.Bash.sh
foo.R
la source
J'utiliserais une variante de l'approche de @ steamer25. Le fait est que je préfère obtenir le dernier script source même lorsque ma session a été lancée via Rscript. L'extrait suivant, lorsqu'il est inclus dans un fichier, fournira une variable
thisScript
contenant le chemin normalisé du script. J'avoue l'utilisation (ab) de source'ing, donc parfois j'invoque Rscript et le script fourni dans l'--file
argument sources un autre script qui en source un autre ... Un jour, j'investirai pour transformer mon code en désordre en un package.la source
99% des cas que vous pourriez simplement utiliser:
Cela ne fonctionnera pas pour les appels fous où le script n'est pas le premier argument, c'est-à-dire
source(some args, file="myscript")
. Utilisez @ hadley dans ces cas fantaisistes.la source
L'approche de Steamer25 fonctionne, mais uniquement s'il n'y a pas d'espace dans le chemin. Sur macOS au moins, le
cmdArgs[match]
retourne quelque chose comme/base/some~+~dir~+~with~+~whitespace/
pour/base/some\ dir\ with\ whitespace/
.J'ai travaillé autour de cela en remplaçant le "~ + ~" par un simple espace blanc avant de le retourner.
De toute évidence, vous pouvez toujours étendre le bloc else comme l'a fait aprstar.
la source
Si plutôt que le script,
foo.R
connaissant son emplacement de chemin, si vous pouvez changer votre code pour toujours référencer toussource
les chemins d'un communroot
alors ceux-ci peuvent être d'une grande aide:Donné
/app/deeply/nested/foo.R
/app/other.R
Cela fonctionnera
Voir https://rprojroot.r-lib.org/ pour savoir comment définir les racines du projet.
la source
la source
Étonnant, il n'y a pas de structure de type «$ 0» dans R! Vous pouvez le faire avec un appel system () à un script bash écrit en R:
Ensuite, divisez simplement le nom scriptpath.sh pour other.R
la source
readLink: illegal option -- e usage: readLink [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
En regardant la pile d'appels, nous pouvons obtenir le chemin de fichier de chaque script en cours d'exécution, les deux plus utiles seront probablement soit le script en cours d'exécution, soit le premier script à trouver (entrée).
la source