override S3 methods in base R - r

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.

Related

A note on graphics::curve() in R CMD check

I use the following code in my own package.
graphics::curve( foo (x) )
When I run R CMD check, it said the following note.How do I delete the NOTE?
> checking R code for possible problems ... NOTE
foo: no visible binding for global variable 'x'
Undefined global functions or variables:
x
Edit for the answers:
I try the answer as follows.
function(...){
utils::globalVariables("x")
graphics::curve( sin(x) )
}
But it did not work. So,..., now, I use the following code, instead
function(...){
x <-1 # This is not used but to avoid the NOTE, I use an object "x".
graphics::curve( sin(x) )
}
The last code can remove the NOTE.
Huuum, I guess, the answer is correct, but, I am not sure but it dose not work for me.
Two things:
Add
utils::globalVariables("x")
This can be added in a file of its own (e.g., globals.R), or (my technique) within the file that contains that code.
It is not an error to include the same named variables in multiple files, so the same-file technique will preclude you from accidentally removing it when you remove one (but not another) reference. From the help docs: "Repeated calls in the same package accumulate the names of the global variables".
This must go outside of any function declarations, on its own (top-level). While it is included in the package source (it needs to be, in order to have an effect on the CHECK process), but otherwise has no impact on the package.
Add
importFrom(utils,globalVariables)
to your package NAMESPACE file, since you are now using that function (unless you want another CHECK warning about objects not found in the global environment :-).

Detect methods in other environments in R -- for testing in testthat

Is it possible to allow "UseMethod" to see class functions defined in other environments? See the below code for an example. I would like the h.logical to be detected too such that h(TRUE) would return "logical".
h <- function(x) {
UseMethod("h")
}
h.character <- function(x){ "char"}
h.numeric <- function(x) { "num" }
aa = list(h.logical=function(x){"logical"})
attach(aa)
h("a")
h(10)
h(TRUE)
This code now throws an error in the last line:
Error in UseMethod("h") : no applicable method for 'h' applied to an object of class "logical"
Solving the issue with this example suffices. If that is not possible, I would appreciate help solving the actual use case in another way.
The use case is as follows: I have a package with functions like h above, then I want to add a class to that function. This works fine just adding the new function to .Globalenv. The problem occurs when I want to test this using testthat as I am not allowed to write to .Globalenv within a test. Adding the new class function to some other environment within the test makes it detectable by methods(), however, UseMethod still does not see it and throws an error. Any ideas?
Can I use something else then UseMethod for this purpose or do some other hack while testing to mimic the actual usage?
Any help or pointers to how to handle this is highly appreciated!

How to make a checking function in R having the same style of output as devtools::check

I would like to make a function checking different aspects of a complex list that is outputted by one of my functions. This is to help parametrise this function; there are a lot of parameters influencing the output, and adapting the parametrisation to have the best-fitted output implies a lot of trial and error for the user. In order to facilitate that I would like to make a 'check' function, providing different quantified and logical tests of the output. Ideally, I would like it to have the same style as the output given by devtools::check() or devtools::build(), like this:
I tried to go inside the devtools::check() or devtools::build() functions, but could not find what they use to have this kind of output. Is it possible to have it for the task I have described ?
Try to use cat inside your function in this way to map and show update on the function:
f<-function()
{
cat("checking for file\n")
cat("preparing\n")
}
Output:
f()
checking for file
preparing
Differents colours and palette could be added using package colorout.
This is the pattern used inside devtools package:
cat_rule(left = "Building", right = pkg$package, col = "cyan")

Create new S3 class methods in R

I'm writing a package in which I would like to create a new generic method, called "analyze", wich do different things according to the argument class. Similar to print that has print.lm, print.aov etc.
In the R folder of my package, I created two files, "analyze.lm" and "analyze.aov" that contain eponym functions. However, if I run analyze(fit) on an lm object, it does nothing because R only recognizes analyze.lm and not the root function ("analyze" only).
I've tried adding an "analyze.R" file, which either contained setMethod() (but that errored), setGeneric("analyze", function(x) attributes(x)) (but that did not solve the issue) or an analyze() function that prints "NULL". However, if I then run analyze(fit) on an lm object, in prints NULL instead of running the analyze.lm class method.
How could I create a generic method, similar to base print, that behaves differently according to argument class, and than I maintained splitted in different files (analyze.lm.R, analyze.aov.R etc.). Thanks!
Add a generic function like this:
analyze <- function(object, ...){
UseMethod("analyze")
}

R function Call from Another Function

I need to modify the function gamGPDfit() in the package QRM to solve a problem. The function gamGPDfit() in turn calls other functions fit.GPD(​) and gamGPDfitUp() to compute the estimates of the parameters.
The structure of the function is shown below:
#######################################################
gamGPDfit<-function (..., init = fit.GPD(...) , ...)
{
...
Par<-gamGPDfitUp(...)
...
return (list(...))
}
<environment: namespace:QRM>
#######################################################
Now, when I call fit.GPD(​), I get the function on the command window to make the necessary modifications. However, the other function gamGPDfitUp​() returns
> gamGPDfitUp
Error: object 'gamGPDfitUp' not found
The question is, how do I get such an in-built function within another function? Does it have to do with the environment QRM? If so how do I obtain the function to modify it?.
I have attached the function and the call of the gamGPDfitUp() is indicated in colour red.
There's a couple of things that may come in handy.
One is help(":::") - Accessing exported and internal variables in a namespace. You can access GamGPDfitUp probably by prefixing it with QRM:::.
Another function is fixInNamespace, which allows you to modify functions inside packages. The help page for this one lists a few more interesting tools. Play around with this and it should solve most of your problems.

Resources