Eu tenho um script chamado foo.R
que inclui outro script other.R
, que está no mesmo diretório:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
Mas quero R
descobrir que, other.R
independentemente do diretório de trabalho atual.
Em outras palavras, foo.R
precisa conhecer seu próprio caminho. Como eu posso fazer isso?
Respostas:
Aqui há uma solução simples para o problema. Este comando:
retorna o caminho do arquivo de script atual. Funciona depois que o script foi salvo.
fonte
dirname(sys.frame(1)$ofile)
diretamente do Rstudio. Funciona bem quando o script é executado usando source ("other.R") edirname(sys.frame(1)$ofile)
está dentro"other.R"
.NULL
quando este é colocado em server.R ao usar brilhanteVocê pode usar a
commandArgs
função para obter todas as opções que foram passadas pelo Rscript para o intérprete R real e procurá-las--file=
. Se seu script foi iniciado a partir do caminho ou se foi iniciado com um caminho completo, oscript.name
abaixo começará com a'/'
. Caso contrário, ele deve ser relativo aocwd
e você pode concaturar os dois caminhos para obter o caminho completo.Editar: parece que você precisaria apenas do item
script.name
acima e retira o componente final do caminho. Eu removi acwd()
amostra desnecessária, limpei o script principal e postei o meuother.R
. Apenas salve esse script e oother.R
script no mesmo diretóriochmod +x
, e execute o script principal.main.R :
outro.R :
saída :
É isso que acredito que dehmann está procurando.
fonte
source
como eu pensava que o OP queria - mas talvez eu tenha interpretado mal o requisito dele. Mas eu não posso un-downmod :( Desculpe!other.name <- file.path(script.basename, "other.R")
commandArgs(trailingOnly = FALSE)
server.R em um aplicativo brilhante, recebo[1] "RStudio" "--interactive"
. Nenhuma informação sobre o diretório do qual foi chamado.Eu não conseguia que a solução do Suppressingfire funcionasse quando 'originava' do console R.
Não consegui que a solução da hadley funcionasse ao usar o Rscript.
Melhor dos dois mundos?
fonte
Rscript
esource()
dentro da R. eu sugeriria fazernormalizePath()
nas duas versões, para que ele dê o caminho completo nos dois casos.library(base)
me levou um tempo para descobrir isso lolsource(file.path(dirname(thisFile()), "other.R"))
emfoo.R
. Isso funciona para mim.main.R
identifiquehelper.R
quais fontes que chamathisFile()
. Ele buscará o caminho emmain.R
vez dehelper.R
. Alguma dica aqui?Não me pergunte como funciona, porque eu esqueci: /
fonte
sys.frames
retorna os ambientes da pilha de chamadas, portanto só faz sentido quando chamado de uma função. Tente, por exemplofoo <- function() {bar <- function() print(sys.frames()); bar()}; foo()
,. Não consigo descobrir o código do @ hadley porque os ambientes não têm umofile
membro.source("~/code/test.r")
,PATH
será definido como~/desktop
. Se você apenas avaliar no nível superior, ele retornará NULL.x$ofile
está indefinido eframe_files
vazio.Isso funciona para mim
fonte
Error: RStudio not running
.""
no meu casoA resposta de rakensi de Como localizar um script R é o IMHO mais correto e realmente brilhante. No entanto, ainda é um hack incorporando uma função fictícia. Estou citando aqui, para que seja mais fácil encontrar outras pessoas.
Isso fornece o diretório do arquivo onde a instrução foi colocada (onde a função fictícia está definida). Em seguida, ele pode ser usado para definir o diretório de trabalho e usar caminhos relativos, por exemplo
ou para criar caminhos absolutos
fonte
sourceDir
estava em branco.character(0)
. Sugestões?Meu tudo em um! (- 01/09/2019 atualizado para lidar com o console RStudio)
fonte
Uma variante reduzida da resposta do Supressingfire:
fonte
Isso funciona para mim. Apenas o apaga dos argumentos da linha de comando, retira o texto indesejado, cria um nome de diretório e, finalmente, obtém o caminho completo disso:
fonte
Eu encerrei e estendi as respostas para esta pergunta em uma nova função
thisfile()
no rprojroot . Também funciona para tricôknitr
.fonte
Gostei da solução do steamer25, pois parece a mais robusta para meus propósitos. No entanto, ao depurar no RStudio (no Windows), o caminho não seria definido corretamente. A razão é que, se um ponto de interrupção for definido no RStudio, a fonte do arquivo usará um comando "debug source" alternativo, que define o caminho do script de maneira um pouco diferente. Aqui está a versão final que estou usando no momento e que explica esse comportamento alternativo no RStudio ao depurar:
fonte
Eu tentei quase tudo nesta questão, Obtendo o caminho de um script R , Obter o caminho do script atual , Encontrar o local do arquivo .R atual e o comando R para definir o diretório de trabalho no local do arquivo de origem no Rstudio , mas no final me encontrei manualmente navegando na tabela CRAN e encontrado
scriptName
bibliotecaque fornece a
current_filename()
função, que retorna o caminho completo adequado do script ao buscar no RStudio e também ao chamar via executável R ou RScript.fonte
Package ‘scriptName’ was removed from the CRAN repository.
- E agora? : oEu também tive esse problema e nenhuma das soluções acima funcionou para mim. Talvez com o
source
ou coisas assim, mas não estava claro o suficiente.Achei isso, para mim, solução elegante:
O importante é
fileSnapshot()
que você fornece muitas informações sobre um arquivo. Retorna uma lista de 8 elementos. Quando você escolhepath
como o elemento da lista, o caminho é retornado com\\
como separador; portanto, o restante do código é apenas para alterar isso.Eu espero que isso ajude.
fonte
Você pode agrupar o script r em um script bash e recuperar o caminho do script como uma variável bash da seguinte forma:
fonte
Eu gosto desta abordagem:
fonte
Eu mesmo resolvi isso sozinho. Para garantir a portabilidade do seu script, inicie-o sempre com:
Funciona porque "." traduz como o comando Unix $ PWD. Atribuir essa sequência a um objeto de caractere permite inserir esse objeto de caractere em setwd () e Presto seu código sempre será executado com o diretório atual como diretório de trabalho, independentemente da máquina em que está ou na estrutura do arquivo. localizado. (Bônus extra: o objeto wd pode ser usado com file.path () (ou seja, file.path (wd, "output_directory") para permitir a criação de um diretório de saída padrão, independentemente do caminho do arquivo que leva ao diretório nomeado. Isso exige que você crie o novo diretório antes de referenciá-lo dessa maneira, mas que também pode ser auxiliado com o objeto wd.
Como alternativa, o código a seguir executa exatamente a mesma coisa:
ou, se você não precisar do caminho do arquivo em um objeto, pode simplesmente:
fonte
Observe que o pacote getopt fornece a
get_Rscript_filename
função, que apenas usa a mesma solução apresentada aqui, mas já está escrita para você em um módulo R padrão, portanto, você não precisa copiar e colar a função "get script path" em todos os scripts você escreve.fonte
R -e "library(getopt); testscript.R"
Rscript
.Veja
findSourceTraceback()
o pacote R.utils , quefonte
Eu tive problemas com as implementações acima, pois meu script é operado a partir de um diretório com link simbólico, ou pelo menos é por isso que acho que as soluções acima não funcionaram para mim. Na linha da resposta do @ ennuikiller, envolvi meu Rscript no bash. Defino a variável de caminho usando
pwd -P
, que resolve as estruturas de diretório com links simbólicos. Em seguida, passe o caminho para o Rscript.Bash.sh
foo.R
fonte
Eu usaria uma variante da abordagem do @ steamer25. O ponto é que eu prefiro obter o último script de origem, mesmo quando minha sessão foi iniciada pelo Rscript. O seguinte snippet, quando incluído em um arquivo, fornecerá uma variável que
thisScript
contém o caminho normalizado do script. Confesso o (ab) uso de source'ing, então, às vezes, invoco o Rscript e o script fornecido no--file
argumento origina outro script que origina outro ... Algum dia eu investirei para transformar meu código confuso em um pacote.fonte
99% dos casos você pode simplesmente usar:
Não funcionará para chamadas malucas onde o script não é o primeiro argumento, ou seja
source(some args, file="myscript")
,. Use @ hadley's nesses casos sofisticados.fonte
A abordagem do Steamer25 funciona, mas apenas se não houver espaço em branco no caminho. No macOS, pelo menos, os
cmdArgs[match]
retornos são parecidos/base/some~+~dir~+~with~+~whitespace/
com/base/some\ dir\ with\ whitespace/
.Eu resolvi isso substituindo o "~ + ~" por um espaço em branco simples antes de devolvê-lo.
Obviamente, você ainda pode estender o bloco else como o aprstar fez.
fonte
Se, em vez do script,
foo.R
conhecendo a localização do caminho, se você puder alterar seu código para sempre fazer referência a todossource
os caminhos de um comumroot
, pode ser uma grande ajuda:Dado
/app/deeply/nested/foo.R
/app/other.R
Isso vai funcionar
Veja https://rprojroot.r-lib.org/ para saber como definir as raízes do projeto.
fonte
fonte
Incrível, não existe uma estrutura do tipo '$ 0' no R! Você pode fazer isso com uma chamada system () para um script bash escrito em R:
Em seguida, apenas divida o nome scriptpath.sh para other.R
fonte
readLink: illegal option -- e usage: readLink [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
Observando a pilha de chamadas, podemos obter o caminho do arquivo de cada script sendo executado, os dois mais úteis provavelmente serão o script atualmente em execução ou o primeiro script a ser originado (entrada).
fonte