Komut satırı bağımsız değişkenlerini R CMD BATCH'a iletme


103

R CMD BATCH my_script.RBir Rkomut dosyasını çalıştırmak için bir terminalden kullanıyorum . Şimdi komuta bir argüman iletmek istediğim noktadayım, ancak onu çalıştırırken bazı sorunlar yaşıyorum. Ben yaparsanız R CMD BATCH my_script.R blablao zaman blablayerine R komut yürütülmektedir mevcut bağımsız değişken olarak yorumlanır olmaktan çok, çıktı dosyası haline gelir.

Rscript my_script.R blablaHangisini blablabir argüman olarak doğru bir şekilde iletmeyi denedim , ancak sonra aldığım my_script.Routçıktı dosyasını alamıyorum R CMD BATCH( .Routdosyayı istiyorum ). Ben yapılan çağrının çıkışını yönlendirmek olabilir iken Rscriptkendi seçtiğim bir dosya adına, ben bir şekilde dosyasında yer R giriş komutları almak olmaz R CMD BATCHyapar .Routdosyası.

Dolayısıyla, ideal olarak, R CMD BATCHyöntem aracılığıyla yürütülen bir R betiğine argümanlar iletmenin bir yolunun peşindeyim , ancak Rscriptkarşılaştırılabilir bir .Routdosya oluşturmanın bir yolu varsa, bunu kullanan bir yaklaşımdan memnun olurum .

Yanıtlar:


115

Benim izlenimime göre bu R CMD BATCHbiraz kalıntı. Her durumda, daha yeni Rscriptçalıştırılabilir (tüm platformlarda mevcuttur), commandArgs()komut satırı argümanlarının işlenmesini oldukça kolaylaştırır.

Örnek olarak, işte küçük bir komut dosyası - buna diyelim "myScript.R":

## myScript.R
args <- commandArgs(trailingOnly = TRUE)
rnorm(n=as.numeric(args[1]), mean=as.numeric(args[2]))

Ve işte onu komut satırından çağırmak nasıl görünüyor

> Rscript myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

Düzenle:

Değil ben tavsiye, ama ... bir arada kullanarak olacağımı source()ve sink()Alabileceğiniz, Rscriptbir üretme .Routtarafından üretilen böyle bir dosya R CMD BATCH. Çağrı - Öyle biraz Ar komut dosyası oluşturmak olacaktır it RscriptEcho.R - Eğer Rscript doğrudan dediğiniz. Şöyle görünebilir:

## RscriptEcho.R
args <- commandArgs(TRUE)
srcFile <- args[1]
outFile <- paste0(make.names(date()), ".Rout")
args <- args[-1]

sink(outFile, split = TRUE)
source(srcFile, echo = TRUE)

Gerçek komut dosyanızı çalıştırmak için şunları yaparsınız:

Rscript RscriptEcho.R myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

myScript.RSağlanan bağımsız değişkenlerle çalıştırılacak ve araya eklenen girdi, çıktı ve iletileri benzersiz bir şekilde adlandırılmış olarak toplayacaktır .Rout.

Edit2:
Rscript'i ayrıntılı olarak çalıştırabilir ve ayrıntılı çıktıyı bir dosyaya yerleştirebilirsiniz.

Rscript --verbose myScript.R 5 100 > myScript.Rout

4
Ayrıca R CMD BATCHbir kalıntı olduğu izlenimini edindim. Yine de hoşuma .Routgiden şey, yalnızca komut dosyası çıktısını değil, aynı zamanda .Rbu çıktıyı üreten komut dosyasından girdi komutlarını / açıklamalarını da içeren bir dosya üretmesidir .
Bryce Thomas

1
Seni duyuyorum. Bu (sanırım hala öyle!) Güzel bir yönüydü R CMD BATCH.
Josh O'Brien

5
ama daha iyi yapabileceğini düşünüyorum R CMD BATCHile knitrörneğin Rscript -e "knitr::stitch(commandArgs(TRUE)[1])" my_script.R(eğer yerini alabilir stitchile stitch_rhtmlya stitch_rmdve yüklemeniz gerekir knitrdan Github Ben sadece bir hata buldum beri stitch...)
Yihui Xie

7
Sadece 0.02'mi eklemek için, terminalden yönlendirmeyi kullanmak da kolaydır. Bir örnek, Rscript myfile.R > path/to/mylog.Routstdout'a (ekran) yazdırılmak yerine dosyanın çıktısı dosyanıza kaydedilir .Rout.
James Pringle

4
@JamesPringle'a eklemek için genellikle çıktımın hem ekrana (gerçek zamanlı olarak izlemek için) hem de bir dosyaya (daha sonra bakmak için) yazdırılmasını istiyorum. YaparımRscript myfile.R | tee mylog.Rout
Heisenberg'i

26

Burada açıklanan seçenekleri denedikten sonra, bu yazıyı Forester'dan r-blogger'larda buldum . Düşünülmesi gereken temiz bir seçenek olduğunu düşünüyorum.

Kodunu buraya koydum:

Komut satırından

$ R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)' test.R test.out &

Test.R

##First read in the arguments listed at the command line
args=(commandArgs(TRUE))

##args is now a list of character vectors
## First check to see if arguments are passed.
## Then cycle through each element of the list and evaluate the expressions.
if(length(args)==0){
    print("No arguments supplied.")
    ##supply default values
    a = 1
    b = c(1,1,1)
}else{
    for(i in 1:length(args)){
      eval(parse(text=args[[i]]))
    }
}

print(a*2)
print(b*3)

Test.out'ta

> print(a*2)
[1] 2
> print(b*3)
[1]  6 15 18

Sayesinde Forester'a !


Unutulmaması gereken önemli, eğer argümanlar karakter türündeyse, tek / çift tırnak kullanmaya gerek yoktur. Örneğin: R CMD BATCH '--args a = FolderName' test.R test.out &
d2a2d

Forester'ın gönderisinde belirtildiği gibi --args, anahtar budur. Aynı zamanda R --no-save --no-restore --args a=1 < test.Rve ile de çalışırR --no-save --no-restore < test.R --args a=1
Dave

Bağımsız değişkenleri komut satırından --args'a geçirmenin bir yolu var mı? Diyelim ki komut satırında bir for döngüsü yapmak ve sonra bunu --args satırına göndermek istiyoruz.
user2809432

9

Önce argümanlar koymanız my_script.Rve argümanlarda kullanmanız gerekir -, örn.

R CMD BATCH -blabla my_script.R

commandArgs()-blablabu durumda karakter dizisi olarak alacaktır . Ayrıntılar için yardıma bakın:

$ R CMD BATCH --help
Usage: R CMD BATCH [options] infile [outfile]

Run R non-interactively with input from infile and place output (stdout
and stderr) to another file.  If not given, the name of the output file
is the one of the input file, with a possible '.R' extension stripped,
and '.Rout' appended.

Options:
  -h, --help        print short help message and exit
  -v, --version     print version info and exit
  --no-timing           do not report the timings
  --            end processing of options

Further arguments starting with a '-' are considered as options as long
as '--' was not encountered, and are passed on to the R process, which
by default is started with '--restore --save --no-readline'.
See also help('BATCH') inside R.

2
Ben öyle ve senaryo kullanımda yoksa ben fark args <- commandArgs(FALSE)ve sonra args yazdırmak ben benimkini gibi olmayanlardır dahil tüm argümanların ile bitirmek, --restore, --saveben kullanırsanız, vb commandArgs(TRUE)tüm hiçbir argüman olsun. Sadece kendi ek argümanlarımı almanın bir yolu var mı? --argsümit verici görünüyor, ama onu çalıştırmayı başaramadım ...
Bryce Thomas 13

Argümanları sondan itibaren saymanız gerekir (örn. Beden-2, beden-1, beden) - sizinki her zaman sonunda olacaktır.
ynka

9

R betiğinizde, adı test.R:

args <- commandArgs(trailingOnly = F)
myargument <- args[length(args)]
myargument <- sub("-","",myargument)
print(myargument)
q(save="no")

Komut satırından şunu çalıştırın:

R CMD BATCH -4 test.R

Çıktı dosyanız, test.Rout, bağımsız değişkenin 4R'ye başarıyla geçirildiğini gösterecektir:

cat test.Rout

> args <- commandArgs(trailingOnly = F)
> myargument <- args[length(args)]
> myargument <- sub("-","",myargument)
> print(myargument)
[1] "4"
> q(save="no")
> proc.time()
user  system elapsed 
0.222   0.022   0.236 

4

Bir cevap ekliyorum çünkü tek satırlık bir çözümün her zaman iyi olduğunu düşünüyorum! myRscript.RDosyanızın üstüne aşağıdaki satırı ekleyin:

eval(parse(text=paste(commandArgs(trailingOnly = TRUE), collapse=";")))

Ardından komut dosyanızı aşağıdaki gibi bir şeyle gönderin:

R CMD BATCH [options] '--args arguments you want to supply' myRscript.R &

Örneğin:

R CMD BATCH --vanilla '--args N=1 l=list(a=2, b="test") name="aname"' myscript.R &

Sonra:

> ls()
[1] "N"    "l"    "name"

0

İşte komut satırı argümanlarını işlemenin başka bir yolu R CMD BATCH. Burada daha önceki bir cevaba dayanan yaklaşımım komut satırında argümanlar belirlemenize ve R betiğinizde bazılarını veya tümünü varsayılan değerleri vermenize izin verir.

İşte test.R adını verdiğim bir R dosyası :

defaults <- list(a=1, b=c(1,1,1)) ## default values of any arguments we might pass

## parse each command arg, loading it into global environment
for (arg in commandArgs(TRUE))
  eval(parse(text=arg))

## if any variable named in defaults doesn't exist, then create it
## with value from defaults
for (nm in names(defaults))
  assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]))[[1]])

print(a)
print(b)

Komut satırına yazarsam

R CMD BATCH --no-save --no-restore '--args a=2 b=c(2,5,6)' test.R

sonra R içinde a= 2ve b= olur c(2,5,6). Ama diyebilirim, çıkarabilirim bve başka bir argüman ekleyebilirim c:

R CMD BATCH --no-save --no-restore '--args a=2 c="hello"' test.R

Sonra R'de a= 2, b= c(1,1,1)(varsayılan) ve c="hello" .

Son olarak, çevre konusunda dikkatli olduğumuz sürece, kolaylık sağlamak için R kodunu bir işleve yerleştirebiliriz:

## defaults should be either NULL or a named list
parseCommandArgs <- function(defaults=NULL, envir=globalenv()) {
  for (arg in commandArgs(TRUE))
    eval(parse(text=arg), envir=envir)

  for (nm in names(defaults))
    assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]), envir=envir)[[1]], pos=envir)
}

## example usage:
parseCommandArgs(list(a=1, b=c(1,1,1)))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.