问题
I'm trying to write an R script that takes in 3 arguments when run with Rscript: input file name, whether it has a header or not (values are 'header' or 'no_header', and a positive integer (the number of replacements; its for a bootstrap application). So, when I run it this way:
Rscript bootstrapWithReplacement.R survival.csv header 50
it should, before running, check if: 1) The script indeed took in 3 parameters; 2) whether the first parameter is a file; 3) whether the second parameter has a 'header' or 'no_header' value, and 4) if the number passed is a positive integer.
Here is my code so far:
pcArgs <- commandArgs()
snOffset <- grep('--args', pcArgs)
inputFile <- pcArgs[snOffset+1]
headerSpec <- pcArgs[snOffset+2] ## header/no_header
numberOfResamples <- pcArgs[snOffset+3] ## positive integer
check.integer <- function(N){
!length(grep("[^[:digit:]]", as.character(N)))
}
if (!file_test("-f",inputFile)) {stop("inputFile not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!exists("headerSpec")) {stop("headerSpec not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!exists("numberOfResamples")) {stop("numberOfResamples not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if ((headerSpec != 'header') == TRUE & (headerSpec != 'no_header') == TRUE) {stop("headerSpec not properly defined. Correct values: 'header' OR 'no_header'.")}
if (check.integer(numberOfResamples) != TRUE | (numberOfResamples>0) != TRUE) {stop("numberOfResamples not properly defined. Must be an integer larger than 0.")}
if (headerSpec == 'header') {
inputData<-read.csv(inputFile)
for (i in 1:numberOfResamples) {write.csv(inputData[sample(nrow(inputData),replace=TRUE),], paste("./bootstrap_",i,"_",inputFile,sep=""), row.names=FALSE)}
}
if (headerSpec == 'no_header') {
inputData<-read.table(inputFile,header=FALSE)
for (i in 1:numberOfResamples) {write.table(inputData[sample(nrow(inputData),replace=TRUE),], paste("./bootstrap_",i,"_",inputFile,sep=""),
sep=",", row.names=FALSE, col.names=FALSE)}
}
My problem is, the check for the existence of a file works, but for the header or integer don't.
Also, how can I, in the beginning, check if all three arguments have been passed?
Thanks!
回答1:
As Vincent said, you should use the trailingOnly
argument to commandArgs
to simplify things.
As Konrad said, never, ever, ever compare directly to TRUE
and FALSE
.
Also, use assertive
for doing assertions.
library(assertive)
library(methods)
cmd_args <- commandArgs(TRUE)
if(length(cmd_args) < 3)
{
stop("Not enough arguments. Please supply 3 arguments.")
}
inputFile <- cmd_args[1]
if (!file_test("-f", inputFile))
{
stop("inputFile not defined, or not correctly named."
}
headerSpec <- match.arg(cmd_args[2], c("header", "no_header"))
numberOfResamples <- as.numeric(cmd_args[3])
assert_all_numbers_are_whole_numbers(numberOfResamples)
assert_all_are_positive(numberOfResamples)
message("Success!")
回答2:
I managed to solve all the checks, here's how:
if ((length(pcArgs) == 8) == FALSE) {stop("Not enough arguments. Please supply 3 arguments. Proper use example: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!file_test("-f",inputFile)) {stop("inputFile not defined, or not correctly named. Proper use example: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if ((headerSpec != 'header') == TRUE & (headerSpec != 'no_header') == TRUE) {stop("headerSpec not properly defined. Correct values: 'header' OR 'no_header'.")}
if (check.integer(numberOfResamples) != TRUE | (numberOfResamples>0) != TRUE) {stop("numberOfResamples not properly defined. Must be an integer larger than 0.")}
Thanks everyone!
来源:https://stackoverflow.com/questions/19345924/how-to-check-if-arguments-have-been-correctly-passed-to-rscript-on-windows