Qual é a melhor maneira de usar scripts R na linha de comando (terminal)?

115

É muito conveniente ter scripts R para fazer plotagens simples na linha de comando. No entanto, executar R a partir de scripts bash não é nada conveniente. O ideal pode ser algo como

#!/path/to/R
...

ou

#!/usr/bin/env R
...

mas não fui capaz de fazer nenhum desses funcionar.

Outra opção é manter os scripts puramente em R, por exemplo script.R, e invocá-los com R --file=script.Rou semelhante. No entanto, ocasionalmente, um script dependerá de opções de linha de comando obscuras em que parte do código existe fora do script. Exemplo: inserir coisas em R do bash por meio de um .Rprofile local, as opções desejadas são, então, tudo --vanillaindica, exceto --no-init-file.

Outra opção é um script bash para armazenar os sinalizadores R e ser executável sem dor, que então chama o script R. O problema é que isso significa que um único programa acabou de ser dividido em dois arquivos que agora devem ser mantidos em sincronia, transferidos para novas máquinas juntos, etc.

A opção que eu menos desprezo atualmente é incorporar o R ​​em um script bash:

#!/bin/bash
... # usage message to catch bad input without invoking R
... # any bash pre-processing of input
... # etc
R --random-flags <<RSCRIPT
# R code goes here
RSCRIPT

Tudo está em um único arquivo. É executável e lida facilmente com argumentos. O problema é que combinar bash e R dessa forma elimina praticamente a possibilidade de qualquer IDE não falhar em um ou no outro e faz meu coração doer muito.

Existe alguma maneira melhor que estou perdendo?

blahdiblah
fonte

Respostas:

132

Conteúdo de script.r:

#!/usr/bin/env Rscript

args = commandArgs(trailingOnly = TRUE)
message(sprintf("Hello %s", args[1L]))

A primeira linha é a linha shebang . É uma prática recomendada usar em /usr/bin/env Rscriptvez de codificar o caminho para sua instalação R. Caso contrário, você corre o risco de seu script quebrar em outros computadores.

Em seguida, torne-o executável (na linha de comando):

chmod +x script.r

Invocação da linha de comando:

./script.r world
# Hello world
Konrad Rudolph
fonte
1
Sim, acho que essa é a maneira "oficial" de fazer isso.
Frank
5
E a execução Rscript --helpda linha de comando listará muitas opções úteis que podem ser adicionadas ao shebang, como --vanilla.
flodel
8
Vamos também mencionar a commandArgsfunção e os pacotes getopte optparsepara analisar a linha de comando. Para que argumentos e opções também possam ser passados ​​para seus scripts ao executar a partir da linha de comando.
flodel
1
Observe que isso só funciona se #!/usr/bin/Rscript(o que não é a prática padrão para scripts R).
acelerado em
16

Experimente um pouco mais . littlerfornece capacidade hash-bang (ou seja, script começando com #! / algum / caminho) para GNU R, bem como linha de comando simples e uso de tubulação.

Jouni K. Seppänen
fonte
10

A resposta de Miguel Sanchez é como deveria ser. A outra maneira de executar o Rscript poderia ser o comando 'env' para executar o RScript de todo o sistema.

#!/usr/bin/env Rscript
The_Cute_Hedgehog
fonte
1
Não "para todo o sistema", mas envpermitiria que você execute o primeiro Rscriptencontrado por conta própria $PATH, permitindo, assim, executar algo diferente de todo o sistema / padrão Rscript(que pode não estar instalado /usr/whatever). Eu recomendaria usar envpara Re Rscriptoutras coisas, uma vez que estes, em particular, podem não ser instalados em locais padrão. ( bashScripts comuns, no entanto, podem sempre usar com segurança #!/bin/bash.)
michael
@michael Não, você está errado em relação ao Bash, e este é um conselho perigoso. A única coisa que pode ser codificada com segurança é /bin/sh. Todo o resto deve usar envlookup. Em particular, na maioria das vezes, o Bash está desatualizado em clusters de computação e os usuários têm suas próprias instalações personalizadas (geralmente em ~/.local/bin, ou compartilhadas em algo como uma /softwaremontagem NFS). Da mesma forma, no macOS, /bin/bashestá sempre desatualizado devido a problemas de licenciamento, e um Bash atualizado é mais comumente localizado em /usr/local/bin/bash(sei que seu comentário tem 3 anos, mas isso é bastante importante).
Konrad Rudolph
Não, desculpe, isso simplesmente não é verdade. Você tem uma opinião forte sobre o assunto, portanto, não vou debater o assunto. Se o uso /bin/sh, em qualquer circunstância, também não é "perigoso", então você tem que admitir que o mesmo pode ser dito /bin/bash. O uso envé mais imprevisível, devido às PATHconfigurações confiáveis ​​/ inconsistentes para diferentes usuários, mas cada usuário R pode realmente querer esse comportamento, enquanto os bashscripts não. Por último, para CI / nuvem que invoca scripts bash mais recentes, simplesmente invoque-os usando /path/to/my/bash myscriptou defina explicitamente o caminho e invoque-os usando env script. EOT
michael
9

#!/path/to/Rnão funcionará porque o próprio R é um script, portanto, execveé infeliz.

eu uso R --slave -f script


fonte
4
Fyi para leitores casuais: muitas dessas respostas são anteriores Rscript(e littler), caso você esteja se perguntando.
michael
@michael Nenhuma das respostas aqui é anterior ao Rscript, que foi lançado em 2007 com o R 2.5.0.
Konrad Rudolph
4

Isso funciona,

#!/usr/bin/Rscript

mas não sei o que acontece se você tiver mais de 1 versão do R instalada em sua máquina.

Se você fizer assim

#!/usr/bin/env Rscript

diz ao intérprete para usar apenas o que R aparecer primeiro em seu caminho.

Hernamesbarbara
fonte
2

Se o programa que você está usando para executar seu script precisa de parâmetros, você pode colocá-los no final de #! linha:

#!/usr/bin/R --random --switches --f

Não sabendo R, não consigo testar corretamente, mas isso parece funcionar:

axa@artemis:~$ cat r.test
#!/usr/bin/R -q -f
error
axa@artemis:~$ ./r.test
> #!/usr/bin/R -q -f
> error
Error: object "error" not found
Execution halted
axa@artemis:~$
Andrew Aylett
fonte
2

Apenas uma nota para adicionar a este post. Versões posteriores de Rparecem ter se enterrado Rscriptum pouco. Para R 3.1.2-1 no OSX baixado em janeiro de 2015, encontrei Rscriptem

/sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

Portanto, em vez de algo como #! /sw/bin/Rscript, eu precisava usar o seguinte no início do meu script.

#! /sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

Isso locate Rscriptpode ser útil para você.

John
fonte
Essa resposta é potencialmente útil, pois não está claro a qual plataforma (* nix ou Mac OS) o OP se refere. Com um pouco de trabalho novamente (procure formatar o código e remover o início apologético), isso seria uma boa adição às respostas aqui.
BenBarnes
2
Esta é outra razão para usar em #!/usr/bin/env Rscriptvez de um caminho codificado em Rscripts (e adicionar esse caminho longo ao seu $PATH)
michael
0

Você pode querer usar o módulo rpy2 do python. No entanto, a maneira "certa" de fazer isso é com R CMD BATCH. Você pode modificar isso para gravar em STDOUT, mas o padrão é gravar em um arquivo .Rout. Veja o exemplo abaixo:

[ramanujan:~]$cat foo.R
print(rnorm(10))
[ramanujan:~]$R CMD BATCH foo.R
[ramanujan:~]$cat foo.Rout

R version 2.7.2 (2008-08-25)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

[Previously saved workspace restored]


 ~/.Rprofile loaded.
Welcome at  Fri Apr 17 13:33:17 2009
> print(rnorm(10))
 [1]  1.5891276  1.1219071 -0.6110963  0.1579430 -0.3104579  1.0072677 -0.1303165  0.6998849  1.9918643 -1.2390156
>

Goodbye at  Fri Apr 17 13:33:17 2009
> proc.time()
   user  system elapsed
  0.614   0.050   0.721

Nota: você vai querer experimentar o --vanilla e outras opções para remover todos os problemas de inicialização.

Ramanujan
fonte
0

Experimente smallR para escrever scripts R rápidos na linha de comando:

http://code.google.com/p/simple-r/

( rcomando no diretório)

A plotagem a partir da linha de comando usando smallR ficaria assim:

r -p file.txt
Tom
fonte
2
Em vez disso (que parece morto), littlercertamente seria o preferido (já que ainda está vivo); ou, apenas use Rscript(que realmente saiu depois de littlerser criado.)
Michael
-1

O seguinte funciona para mim usando o MSYS bash no Windows - não tenho R na minha máquina Linux, então não posso tentar lá. Você precisa de dois arquivos - o primeiro, chamado runr, executa R com um parâmetro de arquivo

# this is runr
# following is path to R on my Windows machine
# plus any R params you need
c:/r/bin/r --file=$1

Você precisa tornar este executável com chmod + x runr .

Em seguida, em seu arquivo de script:

#!runr
# some R commands
x = 1
x

Note o #! A linha runr pode precisar incluir o caminho completo para runr, dependendo de como você está usando o comando, como sua variável PATH está definida, etc.

Não é bonito, mas parece funcionar!


fonte
1
E quanto aos diferentes scripts R que precisam de parâmetros diferentes? Que tal passar argumentos para os scripts R a partir da linha de comando?
blahdiblah