R CMD BATCH에 명령 줄 인수 전달


102

나는 스크립트 R CMD BATCH my_script.R를 실행하기 위해 터미널에서 사용 하고 R있습니다. 이제 명령에 인수를 전달하고 싶지만 작동하는 데 몇 가지 문제가 있습니다. 내가 할 경우 R CMD BATCH my_script.R blabla다음 blabla오히려 R 스크립트가 실행되는 사용할 수 인수로 해석되는 것이 아니라, 출력 파일이됩니다.

나는 인수로 올바르게 Rscript my_script.R blabla전달되는 것처럼 보이는 것을 시도했지만 내가 얻는 출력 파일을 얻지 못했습니다 ( 파일을 원합니다 ). 호출의 출력을 내가 선택한 파일 이름으로 리디렉션 할 수 있지만 파일에서하는 방식으로 파일에 R 입력 명령이 포함 되지 않습니다 . blablamy_script.RoutR CMD BATCH.RoutRscriptR CMD BATCH.Rout

그래서 이상적으로는 R CMD BATCH메소드 를 통해 실행되는 R 스크립트에 인수를 전달하는 방법을 찾고 있지만 Rscript비교 가능한 .Rout파일을 생성하는 방법이 있으면 사용하는 방법에 만족할 것 입니다.

답변:


114

내 인상은 그것이 R CMD BATCH약간의 유물이라는 것입니다. 어쨌든 최신 Rscript실행 파일 (모든 플랫폼에서 사용 가능)과 함께 commandArgs()명령 줄 인수를 매우 쉽게 처리 할 수 ​​있습니다.

예를 들어, 여기에 작은 스크립트가 있습니다 "myScript.R".

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

그리고 다음은 명령 줄에서 호출하는 모습입니다.

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

편집하다:

아니 내가 추천,하지만 ...의 조합을 사용하여 거라고 source()그리고 sink()당신이 얻을 수 Rscript생산 .Rout에 의해 생산 같은 파일을 R CMD BATCH. 전화 - 한 가지 방법은 약간의 R 스크립트를 작성하는 것입니다 그것을 RscriptEcho.R - 당신이 RSCRIPT 직접 부른다. 다음과 같이 보일 수 있습니다.

## 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)

실제 스크립트를 실행하려면 다음을 수행합니다.

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

myScript.R제공된 인수와 함께 실행 되고 인터리브 된 입력, 출력 및 메시지를 고유 한 .Rout.

Edit2 :
Rscript를 자세히 실행하고 자세한 출력을 파일에 배치 할 수 있습니다.

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

4
R CMD BATCH유물 이라는 인상도 받고 있습니다. 내가 좋아하는 점은 .Rout스크립트 출력뿐만 아니라 .R해당 출력을 생성 한 스크립트 파일 의 입력 명령 / 주석도 포함하는 파일을 생성한다는 것입니다.
Bryce Thomas

1
들려요. 그것은 (아직도 그렇다고 생각합니다!)의 좋은 측면이었습니다 R CMD BATCH.
Josh O'Brien

5
하지만 난 당신보다 더 잘 할 수 있다고 생각 R CMD BATCH을 가진 knitr예를 들면, Rscript -e "knitr::stitch(commandArgs(TRUE)[1])" my_script.R(당신은 대체 할 수 stitchstitch_rhtmlstitch_rmd, 그리고 당신은 설치할 필요가 knitr에서 Github에서 나는 그냥 버그를 발견하기 때문에 stitch...)
Yihui시에

7
내 0.02를 추가하기 만하면 터미널에서 리디렉션을 사용하는 것도 쉽습니다. 예를 들어 Rscript myfile.R > path/to/mylog.Routstdout (화면)에 인쇄하는 대신 파일의 출력이 파일에 저장 .Rout됩니다.
James Pringle 2014 년

4
@JamesPringle에 추가하기 위해 종종 내 출력물이 화면 (실시간으로 모니터링)과 파일 (나중에 볼)에 모두 인쇄되기를 원합니다. I doRscript myfile.R | tee mylog.Rout
Heisenberg 2005

26

여기에 설명 된 옵션을 시도한 후 Forester 의이 게시물 을 r-bloggers에서 찾았 습니다 . 고려해야 할 깨끗한 옵션이라고 생각합니다.

여기에 그의 코드를 넣었습니다.

명령 줄에서

$ 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에서

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

Forester 에게 감사드립니다 !


인수가 문자 유형이면 작은 따옴표 / 큰 따옴표를 사용할 필요가 없습니다. 예 : R CMD BATCH '--args a = FolderName'test.R test.out &
d2a2d

Forester의 게시물에서 언급했듯이 --args핵심입니다. 또한 작동 R --no-save --no-restore --args a=1 < test.R하고R --no-save --no-restore < test.R --args a=1
데이브

명령 줄에서 --args로 인수를 전달하는 방법이 있습니까? 따라서 명령 줄에서 for 루프를 수행 한 다음 --args 줄로 보내고 싶다고 가정 해 보겠습니다.
user2809432

9

R 스크립트에서 다음을 호출합니다 test.R.

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

명령 줄에서 다음을 실행합니다.

R CMD BATCH -4 test.R

출력 파일 인 test.Rout은 인수 4가 R에 성공적으로 전달되었음을 보여줍니다 .

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 

8

인수 앞에 인수를 넣고 인수에 my_script.R사용해야 -합니다. 예 :

R CMD BATCH -blabla my_script.R

commandArgs()-blabla이 경우 문자열로 수신 됩니다. 자세한 내용은 도움말을 참조하십시오.

$ 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
내가 이런 식으로하고 스크립트의 사용을한다면 나는 통지 args <- commandArgs(FALSE)하고 인수를 인쇄 난 내처럼되지 않는 포함한 모든 인수와 끝까지, --restore, --save내가 사용하는 경우 등을 commandArgs(TRUE)내가 전혀 인수를 얻을합니다. 내 자신의 추가 주장을 얻을 수있는 방법이 있습니까? --args... 약속 보이지만, 나는 일에 그것을 얻을 수 없었던
브라이스 토마스

끝에서 인수를 세어야합니다 (예 : 크기 -2, 크기 -1, 크기)-항상 끝 부분에 있습니다.
ynka

4

한 줄 솔루션이 항상 좋다고 생각하기 때문에 답변을 추가합니다! myRscript.R파일 맨 위에 다음 행을 추가하십시오.

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

그런 다음 다음과 같이 스크립트를 제출하십시오.

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

예를 들면 :

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

그때:

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

0

다음은를 사용하여 명령 줄 인수를 처리하는 또 다른 방법 R CMD BATCH입니다. 여기대한 이전 답변 을 기반으로 내 접근 방식을 사용하면 명령 줄에서 인수를 지정하고 R 스크립트에서 일부 또는 전체 기본값을 제공 할 수 있습니다.

다음은 test.R 이라는 이름의 R 파일입니다 .

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)

명령 줄에서 입력하면

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

그러면 R 내에 a= 2b=가 c(2,5,6)있습니다. 그러나 나는 말하고 생략 b하고 다른 주장을 추가 할 수있다 c.

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

그런 다음 R에는 a= 2, b= c(1,1,1)(기본값) 및 c=가 "hello"있습니다.

마지막으로 편의를 위해 환경에주의를 기울이는 한 R 코드를 함수로 래핑 할 수 있습니다.

## 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)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.