readArgs | R Documentation |
When providing arguments to an R script, it is often necessary to quote the arguments such that they are interpreted correctly by the shell before being passed to the script. However, this comes with the issue of different quoting conventions for different shells, meaning that the strings will not be interpreted the same between different shells. Additionally, some characters may not be allowed for certain shells.
You can get around this with writeArgs
which will right your arguments
(and comments!) to a file, and returns a filename that can be used in the
arguments place.
readArgs
is the corresponding function to read those arguments back
into R.
writeArgs(x, file = tempfile(pattern = pattern, fileext = fileext),
pattern = "args", fileext = ".Rargs", comments = TRUE,
nlines.between.comment.and.args = 0, nlines.between.args = 2,
at = TRUE, name = NULL)
readArgs(file, name = NULL)
x |
any R object. If a list, each element will be turned into a
character vector (in the same way as |
file |
character string or |
pattern , fileext |
character string. Allows for easier means of editing the filename created. |
comments |
logical. Should the |
nlines.between.comment.and.args |
a non-negative integer specifying the number of empty lines between each set of comments and arguments. |
nlines.between.args |
a non-negative integer specifying the number of
empty lines between each set of arguments. Only used for a list |
at |
logical. Should an |
name |
The name of the format for reading/writing, see Details.
For writing, will be ignored if |
readArgs
and writeArgs
accept many formats for reading and
writing arguments, based on the file extension.
".Rargs"
Arguments are read as though
they were R strings, separated by newline "\n"
or semicolon
" ; "
. This means arguments must be quoted and can use any of the
escape sequences seen in Quotes. The most reliable method,
also the slowest (but not by much). Can contain R comments, will be
ignored when read.
".pyargs"
Arguments are read one per line. No quoting rules apply. Arguments cannot contain newline or carriage return, and will not be read/written properly if so. The fastest method. Cannot contain comments.
".csv"
Arguments are
read using scan
, delimited/separated by comma
","
. Arguments may be quoted with double quotes "\""
, and
must be quoted if they contain comma, newline, or double quotes.
Arguments cannot contain carriage return. Cannot contain comments.
".tsv"
Arguments are read
using scan
, delimited/separated by tab "\t"
.
Arguments may be quoted with double quotes "\""
, and must be
quoted if they contain tab, newline, or double quotes. Arguments cannot
contain carriage return. Cannot contain comments.
Arguments are read using
scan
, delimited/separated by ‘white-space’.
Arguments may be quoted with single quotes "'"
and double quotes
"\""
, and must be quoted if they contain white-space, single
quotes, or double quotes. Arguments cannot contain carriage return.
Quoted arguments cannot contain an odd number of trailing backslashes,
nor an odd number of backslashes before an embedded quoting character.
Can contain comments, marked by a non-quoted hash character "#"
.
The methods listed above can read/write from compressed files (see
gzfile). For "csv"
, "tsv"
, and
"other"
methods, writeArgs
tries to space the text such that
the file will look nice to open within a text editor and ‘Excel’. Each
line of arguments (not comments) will have at most 80 characters (to
look nice in a text editor) or at most 10 columns (to look nice in
‘Excel’), whichever comes first (though this rule is broken by strings
with more than 80 characters).
for file = NULL
, the formatted text.
for file = ""
, the formatted text invisibly.
otherwise, a character string naming a file containing your arguments.
x <- letters; essentials::writeArgs(x, file = "")
comment(x) <- essentials::dedent("
adding a comment
to our arguments
"); essentials::writeArgs(x, file = "")
x <- list(
local({
x <- c("\xC5", "\xC9", "\xD8", "\xEC", "\xFC")
Encoding(x) <- "latin1"
comment(x) <- "accented characters"
x
}),
local({
x <- c("\u{03C3}", "\u{03B4}")
comment(x) <- 'greek letters (default encoding "UTF-8")'
x
}),
local({
x <- "fa\xE7ile"
Encoding(x) <- "latin1" # x is intended to be in latin1
comment(x) <- essentials::dedent(r"{
another non-ASCII character ("unknown" in UTF-8 locale,
"latin1" in IS08859-1, ...)
}")
x
}),
local({
x <- c("\u{7B90}", "\u{5316}", "\u{5B57}")
comment(x) <- 'chinese characters (default encoding "UTF-8")'
x
}),
local({
x <- c("\U{0001D11E}", "\U{0001D4D7}")
comment(x) <- "rarer characters outside the usual 16^4 range"
x
}),
local({
x <- essentials::dedent(r"{
this would be 'rather' annoying to quote for a `shell` on $Unix$,
and even "more" so on Windows because of the \"double\" quotes!
}")
comment(x) <- "all ASCII characters, annoying to quote, hard to read"
x
})
)
comment(x) <- essentials::dedent("
these are some unusual characters
but should still behave correctly
")
# the same arguments in different formats
essentials::writeArgs(x, "", name = "Rargs")
essentials::writeArgs(x, "", name = "pyargs")
essentials::writeArgs(x, "", name = "csv")
essentials::writeArgs(x, "", name = "tsv")
essentials::writeArgs(x, "", name = NULL)
FILE <- essentials::writeArgs(x, at = FALSE)
y <- essentials::readArgs(FILE)
# for the purpose of comparison, we need 'x' to be a character vector
z <- this.path::asArgs(x)
# let's check that the arguments in 'x' match the
# arguments written to and read back from 'FILE' (in 'y')
#
# we don't use 'identical(x, y)' because 'x' has
# attributes (a comment) while 'y' does not
if (length(z) != length(y)) {
cat(gettextf("Catastrophic failure, wrote %d arguments, read %d\n",
length(z), length(y)),
file = stderr())
stop("Please submit a bug report using ",
"utils::bug.report(package = \"essentials\")")
} else if (any(i <- z != y)) {
cat(ngettext(sum(i),
"The following argument was written or read incorrectly!\n",
"The following arguments were written or read incorrectly!\n"),
file = stderr())
print(z[i])
cat("\nIncorrectly written or read as:\n", file = stderr())
print(y[i])
stop("Please submit a bug report using ",
"utils::bug.report(package = \"essentials\")")
} else cat("Yay! The arguments were written and read correctly!\n")
# Using writeArgs and withArgs, Rscript
cat(
essentials::dedent(r"{
withAutoprint({
parser <- essentials::ArgumentParser()
parser$add.argument("args", nargs = "*")
pargs <- parser$parse.args()
print(pargs$args)
})
}"),
file = script <- tempfile(), sep = "\n"
)
this.path::withArgs(
source(script, local = TRUE, echo = FALSE),
paste0("@", FILE)
)
essentials::Rscript("--default-packages=NULL", script, args = paste0("@", FILE))
# reading/writing from/to a compressed file
FILE2 <- essentials::writeArgs(x, at = FALSE, fileext = ".Rargs.gz")
stopifnot(identical(
essentials::readArgs(FILE),
essentials::readArgs(FILE2)
))
# miniscule difference, more desirable with more arguments
c(file.size.original = file.size(FILE),
file.size.compressed = file.size(FILE2))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.