Redefine arguments within an R core package function - r

My fingers are starting to tire of typing update.packages(checkBuilt = T, ask = F). I was wondering whether it's possible to redefine the default parameters within the update.packages() function. So far, I've tried adding the following to my .Rprofile file:
utils::assignInNamespace(
"update.packages",
function(checkBuilt = TRUE, ask = FALSE, ...) {
update.packages(checkBuilt = checkBuilt, ask = ask, ...)
},
"utils"
)
But when I try to use the function in R I get the following error:
update.packages()
Error: C stack usage 7976404 is too close to the limit
I've also just tried using formals() with the following in the .Rprofile:
local({
args_new <- alist(lib.loc = .libPaths(), ask = FALSE, checkBuilt = TRUE)
ind <- which(methods::formalArgs(update.packages) %in% names(args_new))
formals(update.packages)[ind] <- args_new
})
But that results in the following error upon launching R:
Error in formals(update.packages) : object 'update.packages' not found

As #Roland said in the comments, your definition is recursive. You shouldn't bother with the assignInNamespace: keeping the new function in your workspace is good enough. Then you can use utils::update.packages in its definition, e.g.
update.packages <- function(checkBuilt = TRUE, ask = FALSE, ...)
utils::update.packages(checkBuilt = checkBuilt, ask = ask, ...)
You should avoid using assignInNamespace for the reasons listed in its help page.

Related

How to solve unused argument error as part of a meltAssay?

When using meltAssay to convert a SummarizedExperiment object, the central data infrastructure for microbiome analysis in Bioconductor, into long data.frame, I use the following lines according to the instructions in the book:
tse <- transformSamples(tse, method="relabundance")
molten_tse <- meltAssay(tse,
add_row_data = TRUE,
add_col_data = TRUE,
assay_name = "relabundance")
molten_tse
However, I get the following error:
Error in .melt_assay(x, abund_values, feature_name, sample_name, ...)
: unused argument (assay_name = "relabundance")
Use the following syntax instead: (abund_values instead of assay_names.
There seems to be an error in the book)
molten_tse <- meltAssay(tse,
add_row_data = TRUE,
add_col_data = TRUE,
abund_values = "relabundance")

R askYesNo function: print a variable which is a list + strings

I'm a complete newbie in programming with R and stuck at what I believe is actually a very simple question. I've borrowed some code snippets and put them together and everything seems to work, just printing of the package names which has to be installed from GitHub doesn't..
How can I print a Variable which is a list together with strings in the askyesno function. I tried {},[] and doubled them, tried "" and .format as in python, nothing worked.
In the following my Code, please help :)
not_installed = my_packages[!(my_packages %in% installed.packages()[ , "Package"])]
if(length(not_installed)) install.packages(not_installed)
if(length(not_installed != installed.packages()))
still_not_installed = list(not_installed)
Ask = askYesNo("$still_not_installed + cannot be install from CRAN. \n Load from GitHub?",
default = TRUE, prompts = getOption("askYesNo"), gettext(c("Yes", "No", "Cancel")))
if(Ask == TRUE)
p_load_gh("muschellij2/aal", "taiyun/corrplot/blob/master/R/corrplot-package.R",
install = TRUE, dependencies = TRUE)
Do you think this is a proper solution to search for not installed packages and load them?
Your approach to checking for install is not ideal in itself. It will not detect if a package is missing dependencies for example. We can use require which automatically checks if the package is actually usable.
Then we can just build the message with paste.
I assume you will also paste the package into your p_load_gh function, but I don't know the syntax of that particular one.
my_packages <- c("test","test2")
for(p in my_packages)
{
tryCatch(test <- require(p,character.only=T),
warning=function(w) return())
if(!test)
{
print(paste("Package", p, "not found. Installing Package!"))
install.packages(p)
}
tryCatch(test <- require(p,character.only=T),
warning=function(w) return())
if(!test)
{
Ask = askYesNo(paste("Package", p," not installable from CRAN. \n Load from GitHub?", default = TRUE, prompts = getOption("askYesNo"), gettext(c("Yes", "No", "Cancel")))
if(Ask) p_load_gh("muschellij2/aal", "taiyun/corrplot/blob/master/R/corrplot-package.R",
install = TRUE, dependencies = TRUE)
}
}
You can build a message string with paste. toString will nicely concatenate and comma-separate a vector, and then we can paste than on to the rest of your message:
Ask = askYesNo(
msg = paste(toString(still_not_installed),
"cannot be install from CRAN. \n Load from GitHub?"),
default = TRUE,
prompts = getOption("askYesNo"),
gettext(c("Yes", "No", "Cancel"))
)
I think you've got a bigger issue. Line 1: You get the subset of my_packages that are not installed, good. Line 2: you try to install them, fine. Line 3: this is bad. != does element-wise comparison - you're testing if the first not_installed package is not equal to the first installed package (alphabetically), then comparing the second to the second, etc. And then you're testing if the resulting boolean vector has any length---which it will. Instead I would suggest updating the not_installed list, just repeat Line 1 to get the update the list of uninstalled packages. And you don't need to list() them, keep them as a character vector.
Also, we should nest the attempted if(Ask == TRUE) inside the if() of needing github packages at all.
not_installed = my_packages[!(my_packages %in% installed.packages()[ , "Package"])]
if(length(not_installed)) install.packages(not_installed)
still_not_installed = my_packages[!(my_packages %in% installed.packages()[, "Package"])]
if(length(still_not_installed)) {
Ask = askYesNo(
msg = paste(toString(still_not_installed),
"cannot be install from CRAN. \n Load from GitHub?"),
default = TRUE,
prompts = getOption("askYesNo"),
gettext(c("Yes", "No", "Cancel"))
)
if(Ask == TRUE) {
# This code could still be improved, it assumes if we get to
# this point that both packages are missing, but it might
# only be one of them...
p_load_gh(
"muschellij2/aal",
"taiyun/corrplot/blob/master/R/corrplot-package.R",
install = TRUE, dependencies = TRUE)
)
}
}

R6Class bug __Deferred_Default_Marker__

I'm implementing a new R6Class and trying to add new members dynamically (https://cran.r-project.org/web/packages/R6/vignettes/Introduction.html#adding-members-to-an-existing-class) but I get this error "__Deferred_Default_Marker__" (whether it be dynamic or not) when I implement the getx2 function.
Simple <- R6Class("Simple",
public = list(
x = 1,
getx = function() self$x,
getx2 = function() return(self$x * 2)
)
)
# To replace an existing member, use overwrite=TRUE
Simple$set("public", "x", 10, overwrite = TRUE)
s <- Simple$new()
s$getx2() # this returns "__Deferred_Default_Marker__"
Any ideas on this? It's exactly like in the documentation
The solution was to update the package. The problem with the following instruction:
devtools::install_github('r-lib/R6', build_vignettes = FALSE)
was it threw me the following error: namespace 'R6' is imported by 'CompatibilityAPI', 'mrsdeploy' so cannot be unloaded"
so i closed RStudio, and opened R.exe (C:\Program Files\R\R-3.3.3\bin) and ran the same command. Now, I have this package:
Package: R6
Version: 2.2.2.9000
URL: https://github.com/r-lib/R6/
and it works as in the specification.

How to customize clustering in mclust?

I am trying to use the mclust package of R. I want to cluster some data.
Here are the steps to what I have done :
Reading data :
mydata <- read.table("\Users......", row.names= 1, sep = "\t", header = TRUE)
Using mclust : library(mclust)
mydataModel <- Mclust(mydata)
summary(mydataModel)
It breaks into 7 clusters. However, I want my data to be broken only into 2 clusters. Please help on how to do ?
As mentioned by MrFlick, you should read the documentation by adding a ?function().
In your case, do ?Mclust() in your R console to see how default parameters have been set up.
This will show up once you do ?Mclust()
Mclust(data, G = NULL, modelNames = NULL,
prior = NULL,
control = emControl(),
initialization = NULL,
warn = mclust.options("warn"), ...)
All you need to do is:
Mclust(mydata, 2)

How to initialize libraries by their string names in cluster?

I want to initialize libraries in cluster by their names represented as strings.
This code works fine:
library(snowfall, rlecuyer, rsprng)
sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
sfClusterEval(library(e1071))
And this code produces en error: 4 nodes produced errors; first error: object 'expr' not found
library(snowfall, rlecuyer, rsprng)
sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
lib <- "e1071"
expr <- parse(text=paste("library(", lib, ")", sep=""))
sfClusterEval(expr)
So sfClusterEval try to evaluate expr and not an expression which expr contains. I cannot undestand which type of expression should be passed to sfClusterEval function, which uses substitute in its body
> sfClusterEval
function (expr, stopOnError = TRUE)
{
sfCheck()
if (sfParallel()) {
return(sfClusterCall(eval, substitute(expr), env = globalenv(),
stopOnError = stopOnError))
}
else {
return(eval(expr, envir = globalenv(), enclos = parent.frame()))
}
}
This question seems simple, but I could not solve it and need someone's advice.
UPDATE:
Further investigation details on simplier examples. I feel that the truth is near.
This code works fine
sfClusterEval(library("e1071"))
But this call produces en error: 4 nodes produced errors; first error: object 'lib' not found
lib <- "e1071"
sfClusterEval(library(lib, character.only=TRUE))
ANSWER:
The variable lib should be exported to the cluster previously. And after that it can be removed.
lib <- "e1071"
sfExport("lib")
sfClusterEval(library(lib, character.only=TRUE))
sfRemove("lib")
Thanks for Richie, for giving the starting idea!
You can use sfLibrary to load extra packages on workers. See ?snowfall and click snowfall-tools.
Whether in a cluster or not, you simply use the character.only argument to library.
library("e1071", character.only = TRUE)
If your nodes report an error stating that they can't find the package, double check that the package is installed on that machine, in a location that is one of .libPaths(). If all else fails, explicitly provide the location of the package in the lib.loc argument to library.

Resources