I'm writing some code for an R package that needs to compare the current package version to a record of the package version when it created a file. Basically, if the file was created by an old version of the package, it needs to check for changes to the file format. What I've got now is:
file_version<-get_file_version() # evals to a numeric like 100 or 302
pkg_version<-as.numeric(paste0(unlist(packageVersion('my.package')), collapse=""))
if (file_version < pkg_version) upgrade_fileformat() # checks and performs updates
So, this will work, but it seems like there should be a cleaner way to do this without the function sandwich to assign to the pkg_version variable. Does anyone know a nicer way to do the comparison I've described?
Instead of recording a number, recording packageVersion("my.package") and then when reading coerce to package_version() so that the comparison operators work as expected.
ver <- as.numeric_version("3.10.1")
ver < "3.11"
# [1] TRUE
ver > "3"
# [1] TRUE
Related
Using openxlsx package in R. When I run this:
> openxlsx_getOp("dateFormat")
I get the expected value of [1] "yyyy-mm-dd". However, this code:
> op.openxlsx$openxlsx.dateFormat
returns [1] "mm/dd/yyyy".
Why are these different?
EDIT:
Sorry. I called options("openxlsx.dateFormat" = "yyyy-mm-dd") at the top of my source file. Looks like this is important to specify.
From ?op.openxlsx:
‘openxlsx_getOp()’ retrieves the ‘"openxlsx"’ options found in
‘op.openxlsx’. If none are set (currently ‘NULL’) retrieves the
default option from ‘op.openxlsx’. This will also check that the
intended option is a standard option (listed in ‘op.openxlsx’) and
will provide a warning otherwise.
So I suspect it's set to "yyyy-mm-dd" in your environment, hence the discrepancy.
To double check, you can try running R --vanilla on your machine (or the equivalent under Windows) and see if it has reverted back to the default mm/dd/yyyy
Is there a more elegant (fail-safe/robust, shorter) way of checking whether a dataset (whose name is known as a character string) exists in a package than this?
rda.name <- "Animals" # name of the data set/.rda
rda.name %in% data(package = "MASS")[["results"]][,"Item"]
You can try this approach using exists:
exists(data("Animals", package = "MASS"))
# [1] TRUE
As mentioned in the comment, I cannot replicate Sven's answer (under any recent version of R). The following works, but the usage of suppressWarnings() is rather ugly and the dataset is also loaded when calling data() this way (instead of just checking its existence). As such, I don't think this is preferable over my original version, but perhaps inspires someone to provide a fix.
exists(suppressWarnings(data(list = rda.name, package = "MASS")))
I am using the 'intsvy' package in R Studio to analyze PISA. I am actually replicating code from someone else, so really wondering why the following command does not work (when it works in the other persons coding):
R0 <- pisa.reg.pv(pvlabel="MATH",
x="VIETNAM",
weight="W_FSTUWT",
data=DEVCON8a, export=FALSE)
I get the following error message:
Error in chol2inv(Qr$qr[p1, p1, drop = FALSE]) :
'a' must be a complex matrix
I double checked that all variables are 'numeric':
class(DEVCON8a$W_FSTUWT)
#[1] "numeric"
class(DEVCON8a$VIETNAM)
#[1] "numeric"
class(DEVCON8a$PVxMATH) for the 5 different plausible values
#[1] "numeric"
"Vietnam" is just a dummy (numeric) I created within the data set. The data set is basically the original as downloaded from the PISA, filtered for 8 developing countries (hence DEVCON8, including Vietnam). All the previous coding is basically the same I am working off from the other person, for whom the 'pisa.reg.pv' is working perfectly fine. Could it have sth to do with a newer R version?
Thank you.
Try upgrading R and try executing update.packages().
If problem still persists, please post the data in your question so we can try to assist.
I was trying to acquaint myself with R's nChooseK function but I can't get it to work. I thought it was part of the standard setup (i.e. no additional package needed).
Please help. Here is what I tried:
> nChooseK(10,2)
Error: could not find function "nChooseK"
> n<-4;k<-2
> print(nChooseK(n,k))
Error in print(nChooseK(n, k)) : could not find function "nChooseK"
the last one was an example I saw here: R basic nChooseK
The function is in the R.basic package which is not part of the default R installation. You probably meant to use just choose().
As joran mentions the function nChooseK is a part of R.basic. You can tell this from the example you posted by looking at the top of the page:
You'll notice the "R.basic" in the curley braces which tells you that that function is a part of the "R.basic" package. So to use nChooseK you'll first need to load that package
library(R.basic)
If you don't have R.basic installed yet then you'll need to install it
install.packages("R.basic", contriburl="http://www.braju.com/R/repos/")
library(R.basic)
But as noted the choose function in base R does the same thing
choose(37, 12)
#[1] 1852482996
nChooseK(37, 12)
#[1] 1852482996
I just noticed that there's no version argument to R's require() or library() functions. What do people do when they need to ensure they have at least some minimum version of a package, so that e.g. they know some bug is fixed, or some feature is available, or whatever?
I'm aware of the Depends stuff for package authors, but I'm looking for something to use in scripts, interactive environments, org-mode files, code snippets, etc.
You could use packageVersion():
packageVersion("stats")
# [1] ‘2.14.1’
if(packageVersion("stats") < "2.15.0") {
stop("Need to wait until package:stats 2.15 is released!")
}
# Error: Need to wait until package:stats 2.15 is released!
This works because packageVersion() returns an object of class package_version for which < behaves as we'd like it to (which < will not do when comparing two character strings using their lexicographical ordering).
After reading Paul's pseudocode, here's the function I've written.
use <- function(package, version=0, ...) {
package <- as.character(substitute(package))
library(package, ..., character.only=TRUE)
pver <- packageVersion(package)
if (compareVersion(as.character(pver), as.character(version)) < 0)
stop("Version ", version, " of '", package,
"' required, but only ", pver, " is available")
invisible(pver)
}
It functions basically the same as library(), but takes an extra version argument:
> use(plyr, 1.6)
> use(ggplot2, '0.9')
Error in use(ggplot2, "0.9") :
Version 0.9 of 'ggplot2' required, but only 0.8.9 is available
I am not aware of such a function, but it should be quite easy to make one. You can base it on sessionInfo() or packageVersion(). After loading the packages required for the script, you can harvest the package numbers from there. A function that checks the version number would look like (in pseudo code, as I don't have time right now):
check_version = function(pkg_name, min_version) {
cur_version = packageVersion(pkg_name)
if(cur_version < min_version) stop(sprintf("Package %s needs a newer version,
found %s, need at least %s", pkg_name, cur_version, min_version))
}
Calling it would be like:
library(ggplot2)
check_version("ggplot2", "0.8-9")
You still need to parse the version numbers into something that allows the comparison cur_version < min_version, but the basic structure remains the same.