I see myself keep using the install.package function a lot especially when I have to try out someone else's code or run an example.
I as writing a function that installs and loads a package. I tried the following but it did not work:
inp <- function(PKG)
{
install.packages(deparse(substitute(PKG)))
library(deparse(substitute(PKG)))
}
When I typed inp(data.table), it says
Error in library(deparse(substitute(PKG))) :
'package' must be of length 1
How do I pass library name as argument in this case?
I will appreciate if someone can also direct me to information pertaining to passing any kind of object as argument to a function in R.
library() is throwing an error because it by default accepts either a character or a name as its first argument. It sees deparse(substitute(PKG)) in that first argument, and understandably can't find a package of that name when it looks for it.
Setting character.only=TRUE, which tells library() to expect a character string as its first argument, should fix the problem. Try this:
f <- function(PKG) {
library(deparse(substitute(PKG)), character.only=TRUE)
}
## Try it out
exists("ddply")
# [1] FALSE
f(plyr)
exists("ddply")
# [1] TRUE
Related
For example, in
install.packages("caret")
one must include the quotes around caret. I am wondering if theres a way to avoid that. I have written:
inst.packages <- function (x) {
install.packages(as.character(paste(x)))
}
but the issue here is that caret doesn't exist as an object. Therefore,
inst.packages(caret)
gives Error in paste(caret) : object 'caret' not found.
Is there a way around this? Thanks.
it works
inst.pkg <- function(...){
install.packages(sapply(substitute({ ... })[-1], deparse))
}
inst.pkg(caret)
I want to create a function which includes loading a package that I make within the function. A short example (which doesn't run!):
loadMe <- function(name){
genLib(xxx, libName = name) #make a new library with name "name"
library(name) #load the new library...
}
This does not work! A bit of reproducible code which illustrates my main problem:
library(ggplot) #this works fine
load.this <- "ggplot"
library(load.this) #I want this to load ggplot!
I know the problem is that library() and require() take as an argument an object name which does not exist yet. I have tried wrapping my character string with parse(), deparse(), substitute(), expression(), quote(), etc etc. These all return the same problem:
library(load.this)
# Error in library(loadss) : there is no package called 'loadss'
library(deparse(load.this))
# Error in library(deparse(loadss)) : 'package' must be of length 1
Is there a way to do this?
Use the character.only argument
foo <- "ggplot2"
library(foo,character.only=TRUE)
You say that you have tried using parse(). The following seems to work for me:
eval(parse(text = 'library(MASS)')[1])
I am running an ordinary R script in which I have a self-written function. The function makes use of rm() which often produces warnings I do not want to appear in console output. Any of these solutions:
hiding warnings from rm usage from this particular self-written function,
hiding warnings from all usages of rm (globally for an R session)
would satisfy me.
foo.function <- function(){
rm(foo.object)
print("foo")
}
foo.function()
# [1] "foo"
# Warning message:
# In rm(foo.object) : object 'foo.object' not found
For these particular case of object not found, you may use something like this:
if(exists("foo.object")) rm(foo.object)
If you want to hide other warnings as well, just use suppressWarnings().
I have solved variants of the "no visible binding" notes that one gets when checking their package. However, I am unable to solve the situation when applied to the '<<-' assignment.
Specifically, I had defined and used a local variable in several functions, such as:
fName = function(df){
eval({vName<<-0}, envir=environment(fName))
}
However when I run check() from devtools, I get the error:
fName: no visible binding for '<<-' assignment to 'vName'
So, I tried using a different syntax, as follows:
fName = function(df){
assign("vName",0, envir=environment(fName))
}
But got the check() error:
cannot add bindings to a locked environment
When I tried:
fName = function(df){
assign("vName",0, envir=environment(-1))
}
I got the error:
use of NULL environment is defunct
So, my question is how I can accomplish the assignment operator <<- without getting a note in the check() from devtools.
Thank you.
The easy answer is - Don't use <<- in your package. One Alterna way you can make assignments to an environment (but not a meaningful one) is to create a locked binding.
e <- new.env()
e$vName <- 0L
lockBinding("vName", e)
vName
# Error: object 'vName' not found
with(e, vName)
# [1] 0
e$vName <- 5
# Error in e$vName <- 5 : cannot change value of locked binding for 'vName'
You can also lock an environment, but not a meaningful one.
lockEnvironment(e)
rm(vName, envir = e)
# Error in rm(vName, envir = e) :
# cannot remove bindings from a locked environment
Have a look at help(bindenv), it's a good read.
Updated Since you mentioned you might be waiting to make assignment rather than at load times, have a read of help(globalVariables) It's another best-seller at ?
For globalVariables, the names supplied are of functions or other objects that should be regarded as defined globally when the check tool is applied to this package. The call to globalVariables will be included in the package's source. Repeated calls in the same package accumulate the names of the global variables.
i dont know if it helps after that many years.I had the same problem,and what i did to solve it is :
utils::globalVariables(c("global_var"))
Write this r code somewhere inside the R directory(save it as R file).Whenever you assign a global var assign it also locally like so:
global_var<<-1
global_var<-1
That worked for me.
I am attempting to over-ride the print.anova() function from the R stats package within a local package that I use when teaching. Basically, I want to remove the printing of the heading and add a "total" row without creating a new function (e.g., ANOVA()) with a new class.
The function looks like the following:
print.anova <- function(x,digits=max(getOption("digits")-2,3),
signif.stars=getOption("show.signif.stars"),totalSS=TRUE,rm.heading=TRUE,...) {
if (!any(grepl("Res.Df",colnames(x)))) { # exclusion for multiple lm objects
if (!any(grepl("Levene",attr(x,"heading")))) { # exclusion for levenes.test
if (totalSS) { # add total SS row
x <- rbind(x,c(sum(x$Df),sum(x[,"Sum Sq"]),NA,NA,NA))
row.names(x)[dim(x)[1]] <- "Total"
}
}
}
if (rm.heading) attr(x,"heading") <- NULL # remove heading
stats::print.anova(x,digits=digits,signif.stars=signif.stars,...)
invisible(x)
}
My problem is that I am not sure whether to export this as a function, a method, an S3method, some combination of those, or something else entirely. For example, when I try this (part of roxygenize code):
#'#export
I get the following warning when running Rcmd check:
S3 methods shown with full name in documentation object 'print.anova':
'print.anova'
but the function works as expected when I load my package.
However, if I try this:
#'#method print anova
#'#S3method print anova
I dont' get any warnings or errors with Rcmd check but when I try to use the function in R it finds the original function in the stats package namespace. Furthermore, if I do this
getAnywhere(print.anova)
I get this
2 differing objects matching ‘print.anova’ were found in the following places
package:stats
registered S3 method for print from namespace stats
namespace:NCStats
namespace:stats
Finally, for this version (not using export, but using method and S3method), my roxygen-developed namespace has the following item in it
S3method(print,anova)
Leading to my confusion is that I seem to have had success doing something similar with other functions (e.g., using the method and S3method version with print.summary.lm).
I would appreciate any help in my understanding what I am doing wrong here (or how I can ultimately accomplish this goal). Thank you in advance for any help.
p.s., for what it is worth, I am on Windows 7 (32-bit), R 2.15.2, and using RStudio.
Instead of trying to override the print.anova function you could create your own class which is essentially identical to the anova class. Create an as.myanova function which will turn an anova object into an object of mynanova then write your print.myanova function.