setMethodS3 fails to correctly reassign default function - r

When I create s3 methods in R 2.14.1, and then call them, the s3 objects fail to execute the methods in cases where the method has the same name as functions already loaded into the workspace (i.e. base functions). Instead it calls the base function and returns an error. This example uses 'match'. I never had this problem before today. Since I last ran this code, I installed R 3.0.2, but kept my 2.14.1 version. I ran into some trouble (different trouble) with 3.0.2 due to certain packages not being up to date in CRAN, so I reverted RStudio to 2.14.1, and then this problem cropped up. Here's an example:
rm(list=ls())
library(R.oo)
this.df<-data.frame(letter=c("A","B","C"),number=1:3)
setConstructorS3("TestClass", function(DF) {
if (missing(DF)) {
data= NA
} else {
data=DF
}
extend(Object(), "TestClass",
.data=data
)
})
setMethodS3(name="match", class="TestClass", function(this,letter,number,...){
ret = rep(TRUE,nrow(this$.data))
if (!missing(number))
ret = ret & (this$.data$number %in% number)
if (!missing(letter)){
ret = ret & (this$.data$letter %in% letter)
}
return(ret)
})
setMethodS3("get_data", "TestClass", function(this,...) {
return(this$.data[this$match(...),])
})
hope<-TestClass(this.df)
hope$match()
Error in match(this, ...) : argument "table" is missing, with no default
hope$get_data()
Here's the sessionInfo() for clues:
sessionInfo()
R version 2.14.1 (2011-12-22)
Platform: i386-pc-mingw32/i386 (32-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R.oo_1.13.0 R.methodsS3_1.4.2
loaded via a namespace (and not attached):
[1] tools_2.14.1
I tried a lot of combinations of the arguments in setMethodsS3 with no luck.
How can I fix this?

First, I highly recommend calling S3 methods the regular way and not via the <object>$method(...) way, e.g. match(hope) instead of hope$match(). If you do that, everything works as expected.
Second, I can reproduce this issue with R 3.0.2 and R.oo 1.17.0. There appears to be some issues using the particular method name match() here, because if you instead use match2(), calling hope$match2() works as expected. I've seen similar problems when trying to create S3 methods named assign() and get(). The latter actually generates a error if tried, e.g. "Trying to use an unsafe generic method name (trust us, it is for a good reason): get". I'll add assign() and most likely match() to the list of no-no names. DETAILS: Those functions are very special in R so one should avoid using those names. This is because, if done, S3 generic functions are created for them and all calls will be dispatched via generic functions and that is not compatible with
Finally, you should really really update your R - it's literally ancient and few people will not bother trying to help you with issues unless you run the most recent stable R version (now R 3.0.2 soon to be R 3.1.0). At a minimum, you should make sure to run the latest versions of the package (your R.methodsS3 and R.oo versions are nearly 2 and 1 years old by now with important updates since).
Hope this helps

Related

How to detach formula.tools in R without restarting the session [duplicate]

I'd like to unload a package without having to restart R (mostly because restarting R as I try out different, conflicting packages is getting frustrating, but conceivably this could be used in a program to use one function and then another--although namespace referencing is probably a better idea for that use).
?library doesn't show any options that would unload a package.
There is a suggestion that detach can unload package, but the following both fail:
detach(vegan)
Error in detach(vegan) : invalid name argument
detach("vegan")
Error in detach("vegan") : invalid name argument
So how do I unload a package?
Try this (see ?detach for more details):
detach("package:vegan", unload=TRUE)
It is possible to have multiple versions of a package loaded at once (for example, if you have a development version and a stable version in different libraries). To guarantee that all copies are detached, use this function.
detach_package <- function(pkg, character.only = FALSE)
{
if(!character.only)
{
pkg <- deparse(substitute(pkg))
}
search_item <- paste("package", pkg, sep = ":")
while(search_item %in% search())
{
detach(search_item, unload = TRUE, character.only = TRUE)
}
}
Usage is, for example
detach_package(vegan)
or
detach_package("vegan", TRUE)
You can also use the unloadNamespace command, as in:
unloadNamespace("sqldf")
The function detaches the namespace prior to unloading it.
You can uncheck the checkbox button in RStudio (packages).
I tried what kohske wrote as an answer and I got error again, so I did some search and found this which worked for me (R 3.0.2):
require(splines) # package
detach(package:splines)
or also
library(splines)
pkg <- "package:splines"
detach(pkg, character.only = TRUE)
When you are going back and forth between scripts it may only sometimes be necessary to unload a package. Here's a simple IF statement that will prevent warnings that would appear if you tried to unload a package that was not currently loaded.
if("package:vegan" %in% search()) detach("package:vegan", unload=TRUE)
Including this at the top of a script might be helpful.
I hope that makes your day!
detach(package:PackageName) works and there is no need to use quotes.
Another option is
devtools::unload("your-package")
This apparently also deals with the issue of registered S3 methods that are not removed with unloadNamespace()
You can try all you want to remove a package (and all the dependencies it brought in alongside) using unloadNamespace() but the memory footprint will still persist. And no, detach("package:,packageName", unload=TRUE, force = TRUE) will not work either.
From a fresh new console or Session > Restart R check memory with the pryr package:
pryr::mem_used()
# 40.6 MB ## This will depend on which packages are loaded obviously (can also fluctuate a bit after the decimal)
Check my sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)
Matrix products: default
locale:
[1] LC_COLLATE=English_Canada.1252 LC_CTYPE=English_Canada.1252 LC_MONETARY=English_Canada.1252 LC_NUMERIC=C
[5] LC_TIME=English_Canada.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.6.1 pryr_0.1.4 magrittr_1.5 tools_3.6.1 Rcpp_1.0.3 stringi_1.4.3 codetools_0.2-16 stringr_1.4.0
[9] packrat_0.5.0
Let's load the Seurat package and check the new memory footprint:
library(Seurat)
pryr::mem_used()
# 172 MB ## Likely to change in the future but just to give you an idea
Let's use unloadNamespace() to remove everything:
unloadNamespace("Seurat")
unloadNamespace("ape")
unloadNamespace("cluster")
unloadNamespace("cowplot")
unloadNamespace("ROCR")
unloadNamespace("gplots")
unloadNamespace("caTools")
unloadNamespace("bitops")
unloadNamespace("fitdistrplus")
unloadNamespace("RColorBrewer")
unloadNamespace("sctransform")
unloadNamespace("future.apply")
unloadNamespace("future")
unloadNamespace("plotly")
unloadNamespace("ggrepel")
unloadNamespace("ggridges")
unloadNamespace("ggplot2")
unloadNamespace("gridExtra")
unloadNamespace("gtable")
unloadNamespace("uwot")
unloadNamespace("irlba")
unloadNamespace("leiden")
unloadNamespace("reticulate")
unloadNamespace("rsvd")
unloadNamespace("survival")
unloadNamespace("Matrix")
unloadNamespace("nlme")
unloadNamespace("lmtest")
unloadNamespace("zoo")
unloadNamespace("metap")
unloadNamespace("lattice")
unloadNamespace("grid")
unloadNamespace("httr")
unloadNamespace("ica")
unloadNamespace("igraph")
unloadNamespace("irlba")
unloadNamespace("KernSmooth")
unloadNamespace("leiden")
unloadNamespace("MASS")
unloadNamespace("pbapply")
unloadNamespace("plotly")
unloadNamespace("png")
unloadNamespace("RANN")
unloadNamespace("RcppAnnoy")
unloadNamespace("tidyr")
unloadNamespace("dplyr")
unloadNamespace("tibble")
unloadNamespace("RANN")
unloadNamespace("tidyselect")
unloadNamespace("purrr")
unloadNamespace("htmlwidgets")
unloadNamespace("htmltools")
unloadNamespace("lifecycle")
unloadNamespace("pillar")
unloadNamespace("vctrs")
unloadNamespace("rlang")
unloadNamespace("Rtsne")
unloadNamespace("SDMTools")
unloadNamespace("Rdpack")
unloadNamespace("bibtex")
unloadNamespace("tsne")
unloadNamespace("backports")
unloadNamespace("R6")
unloadNamespace("lazyeval")
unloadNamespace("scales")
unloadNamespace("munsell")
unloadNamespace("colorspace")
unloadNamespace("npsurv")
unloadNamespace("compiler")
unloadNamespace("digest")
unloadNamespace("R.utils")
unloadNamespace("pkgconfig")
unloadNamespace("gbRd")
unloadNamespace("parallel")
unloadNamespace("gdata")
unloadNamespace("listenv")
unloadNamespace("crayon")
unloadNamespace("splines")
unloadNamespace("zeallot")
unloadNamespace("reshape")
unloadNamespace("glue")
unloadNamespace("lsei")
unloadNamespace("RcppParallel")
unloadNamespace("data.table")
unloadNamespace("viridisLite")
unloadNamespace("globals")
Now check sessionInfo():
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)
Matrix products: default
locale:
[1] LC_COLLATE=English_Canada.1252 LC_CTYPE=English_Canada.1252 LC_MONETARY=English_Canada.1252 LC_NUMERIC=C
[5] LC_TIME=English_Canada.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.6.1 stringr_1.4.0 rstudioapi_0.10 pryr_0.1.4 jsonlite_1.6 gtools_3.8.1 R.oo_1.22.0
[8] magrittr_1.5 Rcpp_1.0.3 R.methodsS3_1.7.1 stringi_1.4.3 plyr_1.8.4 reshape2_1.4.3 codetools_0.2-16
[15] packrat_0.5.0 assertthat_0.2.1
Check the memory footprint:
pryr::mem_used()
# 173 MB
Link to screen-cast demonstration
Note also that you can only use unload() once. If you use it a second time without rerunning library(), y'll get the not very informative error message invalid 'name' argument:
library(vegan)
#> Loading required package: permute
#> Loading required package: lattice
#> This is vegan 2.5-6
detach("package:vegan", unload=TRUE)
detach("package:vegan", unload=TRUE)
#> Error in detach("package:vegan", unload = TRUE): invalid 'name' argument
Created on 2020-05-09 by the reprex package (v0.3.0)
I would like to add an alternative solution. This solution does not directly answer your question on unloading a package but, IMHO, provides a cleaner alternative to achieve your desired goal, which I understand, is broadly concerned with avoiding name conflicts and trying different functions, as stated:
mostly because restarting R as I try out different, conflicting packages is getting frustrating, but conceivably this could be used in a program to use one function and then another--although namespace referencing is probably a better idea for that use
Solution
Function with_package offered via the withr package offers the possibility to:
attache a package to the search path, executes the code, then removes the package from the search path. The package namespace is not unloaded, however.
Example
library(withr)
with_package("ggplot2", {
ggplot(mtcars) + geom_point(aes(wt, hp))
})
# Calling geom_point outside withr context
exists("geom_point")
# [1] FALSE
geom_point used in the example is not accessible from the global namespace. I reckon it may be a cleaner way of handling conflicts than loading and unloading packages.
Just go to OUTPUT window, then click on Packages icon (it is located between Plot and Help icons). Remove "tick / check mark" from the package you wanted be unload.
For again using the package just put a "tick or Check mark" in front of package or use :
library (lme4)
Connected with #tjebo answer.
TL;DR
Please use pkgload:::unload instead of devtools::unload as they are the same function (1 to 1) and pkgload is a much lighter package (nr of dependencies). devtools simply reexporting the pkgload:::unload function.
Unfortunately devtools is a huge dependency (as devtools has a lot of own dependencies), which is more development stage targeted. So if you want to use the unload function in your own package or you care about library size please remember to use pkgload:::unload instead of devtools::unload. devtools simply reexporting the pkgload:::unload function.
Please check the footer of the devtools::unload function to quickly confirm the reexport or go to the github repo
> devtools::unload
function (package = pkg_name(), quiet = FALSE)
{
if (package == "compiler") {
oldEnable <- compiler::enableJIT(0)
if (oldEnable != 0) {
warning("JIT automatically disabled when unloading the compiler.")
}
}
if (!package %in% loadedNamespaces()) {
stop("Package ", package, " not found in loaded packages or namespaces")
}
unregister_methods(package)
unloaded <- tryCatch({
unloadNamespace(package)
TRUE
}, error = function(e) FALSE)
if (!unloaded) {
unload_pkg_env(package)
unregister_namespace(package)
}
clear_cache()
unload_dll(package)
}
<bytecode: 0x11a763280>
<environment: namespace:pkgload>

Error: "could not find function "lengths"

While running:
reg_model = glmer(modeling1 ~ pTOT_VIOPT_CT + (1|STUDY_CODE_ALIAS),
data=data_CACZ, family=binomial)
I am getting the error:
Error in .fixupDimnames(.Object#Dimnames) :
could not find function "lengths"
Not sure what could be the possible reason.
FYI: I am putting below the sessionInfo():
R version 3.0.2 (2013-09-25)
Platform: i386-w64-mingw32/i386 (32-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_0.11.5 lme4_1.1-10 Matrix_1.2-3 car_2.0-21 MASS_7.3-29
loaded via a namespace (and not attached):
[1] grid_3.0.2 lattice_0.20-29 minqa_1.2.4 nlme_3.1-118 nloptr_1.0.4 nnet_7.3-7 splines_3.0.2 tools_3.0.2
(From the maintainer of 'Matrix'): This is indeed really strange,
but differently than #nicola suggests.
It is okay to update Recommended packages such as Matrix without updating R. That's indeed one feature of these.
Matrix 1.2-3 is indeed the current version of Matrix on CRAN, which is good.
However, since Matrix 1.2-2, there is the following code in Matrix/R/zzz.R :
if(getRversion() >= "3.2.0") {
......
} else {
......
lengths <- function (x, use.names = TRUE) vapply(x, length, 1L, USE.NAMES = use.names)
}
But that code only works correctly for you, when the Matrix package is built from the source with a correct version of R, i.e. in your case with a version of R before 3.2.0.
This (correctly built) happens for all platforms but Windows (the broken by choice one).
If you really don't want (or can't easily) upgrade your version of R,
you have two other options:
downgrade your version of Matrix to the one that comes with your version of R. As you probably have installed the new Matrix replacing the old one, you need to get that and replace the newer version of Matrix. HOWEVER, I guess you would also have to downgrade lme4, and in the end you suffer too much.
Safer and in principle correct: Install the 'Rtools' collection for Windows (you need the one that matches your version of R !)
including C compiler etc, until the following works correctly
install.packages("Matrix", type = "source")
The work to do this may well be worth it. You will be able to install other R packages from their source, which is very useful anyway
(I would not want to live without this possibility if I had to work with Windows).

Problems using package 'minet' - could not find function mutinformation

When trying to run the sample code that is in the Minet paper / vignette I am experiencing a nunber of issues, e.g.
mim <- build.mim(discretize(syn.data), estimator)
Error in build.mim(dataset, estimator, disc, nbins):
could not find function "mutinformation"
I have also received other errors such as "unknown estimator" when trying methods prefixed with "mi." e.g. "mi.empirical."
I am running windows 8.1. Any help would be much appreciated!
EDIT 1: Additional Information
After playing around some more, the main problem I am having is when trying to use the discretize function like so:
> data(syn.data)
> disc <- "equalwidth"
> nbins <- sqrt(nrow(syn.data))
> ew.data <- discretize(syn.data, disc, nbins)
Error: could not find function "discretize"
This causes the same Error in all functions e.g. build.mim or minet which utilise discretize. I can run build.mim successfully without including discretize.
In addition, I am getting errors if I use minet (whilst excluding the discretize argument) with any of the mi.* estimation methods, e.g.
> res<-minet(syn.data,"mrnet","mi.empirical","equal width",10)
Error in build.mim(dataset, estimator, disc, nbins) :
could not find function "mutinformation"
However, running the same function with the "spearman" estimator works fine.
Edit 2: Output of sessionInfo()
> sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United Kingdom.1252 LC_CTYPE=English_United Kingdom.1252 LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C LC_TIME=English_United Kingdom.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] minet_3.20.0
loaded via a namespace (and not attached):
[1] tools_3.1.0
discretize() is a function from the package infotheo that you can find in CRAN. There are some references to that package in the minet documentation. Maybe the authors of minet have moved some functionality to the infotheo package but since it is not a dependency it does not get installed automatically. It may be worth contacting the authors about this.
library(infotheo)
data(syn.data)
disc <- "equalwidth"
nbins <- sqrt(nrow(syn.data))
ew.data <- discretize(syn.data, disc, nbins)
The same applies for the multiinformation() function(). It is part of the infotheo package.

ns varies for no apparent reason

My results of using splines::ns with a least-squares fit varied with no rhyme or reason that I could see, and I think I have traced the problem to the ns function itself.
I have reduced the problem to this:
require(splines)
N <- 0
set.seed(1)
for (i in 1:100) N <- N + identical(ns(1:10,3),ns(1:10,3))
N
My results average about 39, range 34--44 or so, but I expected 100 every time. Why should the results of ns be random? If I substitute bs for ns in both places, I get 100, as expected. My set.seed(1) hopes to demonstrate that the randomness I get is not what R intended.
In a clean session, using RStudio and R version 2.14.2 (2012-02-29), I get 39, 44, 38, etc. Everyone else seems to be getting 100.
Further info:
Substituing splines::ns for ns gives the same results. A clean vanilla session gives the same results. My computer has 8 cores.
The differences, when they happen, are generally or always 2^-54:
Max <- 0
for (i in 1:1000) Max <- max( Max, abs(ns(1:10,3)-ns(1:10,3)) )
c(Max,2^-54)
with result [1] 5.551115e-17 5.551115e-17. This variability causes me big problems down the line, because my optimize(...)$min now varies sometimes even in the first digit, making results not repeatable.
My sessionInfo with a clean vanilla session:
I created what I understand to be known as a clean vanilla session using
> .Last <- function() system("R --vanilla")
> q("no")
This blows away the session, and when I restart it, I get my clean vanilla session. Then, in answer to Ben Bolker's clarifying question, I did this at the beginning of my clean vanilla session:
> sessionInfo()
R version 2.14.2 (2012-02-29)
Platform: x86_64-pc-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Revobase_6.1.0 RevoMods_6.1.0 RevoScaleR_3.1-0 lattice_0.20-0
[5] rpart_3.1-51
loaded via a namespace (and not attached):
[1] codetools_0.2-8 foreach_1.4.0 grid_2.14.2 iterators_1.0.6
[5] pkgXMLBuilder_1.0 revoIpe_1.0 tools_2.14.2 XML_3.9-1.1
> require(splines)
Loading required package: splines
> N <- 0
> set.seed(1)
> for (i in 1:100) N <- N + identical(ns(1:10,3),ns(1:10,3))
> N
[1] 32
This is the answer I got from REvolution Technical Suppoort (posted here with permission):
The problem here is an issue of floating point arithmetic. Revolution
R uses the Intel mkl BLAS library for some computations, which differs
from what CRAN-R uses and uses this library for the 'ns()'
computation. In this case you will also get different results
depending on whether you are doing the computation on a
Intel-processor based machine or a machine with an AMD chipset.
We do ship the same BLAS and Lapack DLL's that are shipped with
CRAN-R, but they are not the default ones used with Revolution R.
Customers can revert the installed DLL's if they so choose and prefer,
by doing the following:
1). Renaming 'Rblas.dll' to 'Rblas.dll.bak' and 'Rlapack.dll' to
'Rlapack.dll.bak'
in the folder 'C:\Revolution\R-Enterprise-6.1\R-2.14.2\bin\x64'.
2). Rename the files 'Rblas.dll.0' and 'Rlapack.dll.0' in this folder
to Rblas.dll and Rlpack.dll respectively.
Their suggestion worked perfectly. I have renamed these files back and forth several times, using both RStudio (with Revolution R) and Revolution R's own IDE, always with the same result: The BLAS dlls give me N==40 or so, and the CRAN-R dlls give me N==100.
I will probably go back to BLAS, because in my tests, it is 8-times faster for %*% and 4-times faster for svd(). And that is just using one of my cores (verified by the CPU usage column of the Processes tab of Windows Task Manager).
I am hoping someone with better understanding can write a better answer, for I still don't really understand the full ramifications of this.

ffdfdply function crashes R and is very slow

learning how to compute tasks in R for large data sets (more than 1 or 2 GB), I am trying to use ff package and ffdfdply function.
(See this link on how to use ffdfdply: R language: problems computing "group by" or split with ff package )
My data have the following columns:
"id" "birth_date" "diagnose" "date_diagnose"
There are several rows for each "id", and I want to extract the first date where there was a diagnose.
I would apply this :
library(ffbase)
library(plyr)
load(file=file_name); # to load my ffdf database, called data.f .
my_fun <- function(x){
ddply( x , .(id), summarize,
age = min(date_diagnose - birth_date, na.rm=TRUE))
}
result <- ffdfdply(x = data.f, split = data.f$id,
FUN = function(x) my_fun(x) , trace=TRUE) ;
result[1:10,] # to check....
It is very strange, but this command: ffdfdply(x = data.f, .... ) is making RStudio (and R) crash. Sometimes the same command will crash R and sometimes not.
For example, if I trigger again the ffdfdply line (which worked the first time), R will crash.
Also using other functions, data, etc. will have the same effect. There is no memory increase, or anything into log.txt.
Same behaviour when applying the summaryBy "technique"....
So if anybody has the same problem and found the solution, that would be very helpful.
Also ffdfdply gets very slow (slower than SAS...) , and I am thinking about making another strategy to make this kind of tasks.
Is ffdfdply taking into account that for example the data set is ordered by id? (so it does not have to look into all the data to take the same ids... ).
So, if anybody knows other approaches to this ddply problem, it would be really great for all the "large data sets in R with low RAM memory" users.
This is my sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: i386-w64-mingw32/i386 (32-bit)
locale:
[1] LC_COLLATE=Danish_Denmark.1252 LC_CTYPE=Danish_Denmark.1252
[3] LC_MONETARY=Danish_Denmark.1252 LC_NUMERIC=C
[5] LC_TIME=Danish_Denmark.1252
attached base packages:
[1] tools stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] plyr_1.7.1 ffbase_0.6-1 ff_2.2-10 bit_1.1-9
I also noticed this when using the package which we uploaded to CRAN recently. It seems to be caused by overloading in package ffbase the "[.ff" and "[<-.ff" extractor and setter functions from package ff.
I will remove this feature from the package and will upload it to CRAN soon. In the mean time, you can use the version 0.7 of ffbase, which you can get here:
http://dl.dropbox.com/u/25690064/ffbase_0.7.tar.gz
and install it as:
download.file("http://dl.dropbox.com/u/25690064/ffbase_0.7.tar.gz", "ffbase_0.7.tar.gz")
shell("R CMD INSTALL ffbase_0.7.tar.gz")
Let me know if that helped.

Resources