I have a function in a package I'm building that assigns a hex-code to the global environment for use by analysts...
optiplum<-function(){
assign(
x="optiplum",
value=rgb(red=129,green=61,blue=114, maxColorValue = 255),
envir=.GlobalEnv)
}
My unit test code is:
test_that("optiplum - produces the correct hex code",{
optiplum()
expect_true(identical(optiplum,"#813D72"))
})
When I run the code manually, there isn't an error:
> str(optiplum)
chr "#813D72"
> str("#813D72")
chr "#813D72"
> identical("#813D72",optiplum)
[1] TRUE
> expect_true(identical(optiplum,"#813D72"))
When I run a test_file() is also does not error
> test_file("./tests/testthat/test-optiplum.R")
optiplum : .
However, when I run the test as part of my devtools workflow:
> test()
Testing optINTERNAL
Loading optINTERNAL
optiplum : 1
1. Failure: optiplum - produces the correct hex code --------------------------------------------------------------------------------------------------------------
identical(optiplum, "#813D72") isn't true
Anyone have any ideas on why this might be occurring and how I can resolve the situation?
Assignment to the global environment is a no-no, see R Inferno and testthat isolates tests as much as possible (see test_that() details). As a consequence, the optiplum() assignment to the global environment would not succeed because the testthat function strictly prohibits such behaviour.
#Hadley rightly points out that the function should just return the string instead of assigning it, particularly since it is just two extra characters for each use.
So not
optiplum<-function(){
assign(
x="optiplum",
value=rgb(red=129,green=61,blue=114, maxColorValue = 255),
envir=.GlobalEnv)
}
but
optiplum <- function() rgb(red=102,green=17,blue=109, maxColorValue = 255)
Related
I am using R's excellent future package. And in the documentation it mentions %global% and %packages% for assigning global variables and packages to be evaluated in the future environment. But those seem to only work with %<-%.
My question is: is there away to do that with future_apply as well. I tried
x = 1
future.apply::future_sapply(1:50, function(y) {
glue("{x}")
}) %packages% "glue" %globals% "x"
and It doesn't work
If you look at the help page for future_sapply, you'll see that future_lapply has the arguments future.packages and future.globals, and if you read carefully, these are also used in future_sapply. So this works:
x = 1
future.apply::future_sapply(1:50, function(y) {
glue("{x}")
}, future.packages = "glue", future.globals = "x")
When I start up and R script and I like to check their package versions. I tend to run something like
library(dplyr); packageVersion("dplyr")
This works fine, but I'd like to shorten this to a single function that would load a library and then return its version.
I want the libary function to accept either a string of the library name, or just the library name typed in by itself.
I tried this function:
libver <- function(pac){
if(!is.character(pac)){
pac <- deparse(substitute(pac))
}
library(pac, character.only=TRUE)
packageVersion(pac)
}
But this works for string inputs but not non string inputs
libver(MASS)
Error in libver(MASS): object 'MASS' not found
I can hard code it to take objects rather than strings as follows,
libver <- function(pac){
library( deparse(substitute(pac), character.only=TRUE)
packageVersion(deparse(substitute(pac))
}
but I'd like to keep the flexability to do either one if I can.
!is.character(pac) returns an error when pac is the bare package name, without quotation marks. Instead, you can do pac = as.character(substitute(pac)) which will return a character string, regardless of whether the argument was originally a character string.
libver <- function(pac) {
pac = as.character(substitute(pac))
library(pac, character.only=TRUE)
packageVersion(pac)
}
libver <- function(pac){
pac <- gsub("\"","",deparse(substitute(pac)))
library(pac,character.only = T)
packageVersion(pac)
}
libver(dplyr)
[1] ‘0.7.2’
libver("dplyr")
[1] ‘0.7.2’
I'm trying to use dump() to save the settings of my analysis so I can examine them in a text editor or reload them at a later date.
In my code I'm using the command
dump(ls(), settingsOutput, append=TRUE)
The file defined by `settingsOutput' gets created, but the larger objects and locally defined functions are truncated. Here's an excerpt from such a file. Note these files are generally on the order of a few kb.
createFilePrefix <-
function (runDesc, runID, restartNumber)
{
...
createRunDesc <-
function (genomeName, nGenes, nMix, mixDef, phiFlag)
{
...
datasetID <-
"02"
descriptionPartsList <-
c("genomeNameTest", "nGenesTest", "numMixTest", "mixDefTest",
"phiFlagTest", "runDescTest", "runIDTest", "restartNumberTest"
...
diffTime <-
structure(0.531, units = "hours", class = "difftime")
dissectObjectFileName <-
function (objectFileName)
{
...
divergence <-
0
Just for reference, here's one of the functions defined above
createFilePrefix <- function(runDesc, runID, restartNumber){
paste(runDesc, "_run-", runID, "_restartNumber-", restartNumber, sep="")
}
Right now I'm going back and removing the problematic lines and then loading the files, but I'd prefer to actually have code that works as intended.
Can anyone explain to me why I'm getting this behavior and what to do to fix it?
Program : R 3.2.1 for Mac OSX
IDE : RStudio
Output : rmkd > html
Package : "psych"
Function : alpha()
Problem :
While using alpha(data, na.rm=F, check.keys=F, delete=F), because portions of the input-data is negatively correlated and because I have check.keys = FALSE, I get the following message :
Some items XXX were negatively correlated with the total scale and
probably should be reversed. To do this, run the function again with
the 'check.keys=TRUE' option
Question :
My check.keys is set intentionally. Fully understanding the implications of the warning & mostly for aesthetic and educational reasons, how can I suppress it in my output?
Attempts so far :
1. I've tried suppressWarnings() & suppressMessages().
2. I've tried invisible() & sink(., type="message").
3. In the Rmd block, I've tried : ```{r warning=F, message=F}
4. Exploring print(alpha) I found what I think is the origin. Maybe someone understands how to suppress this part of the code? :
`p1 <- principal(x)
if (any(p1$loadings < 0)) {
if (check.keys) {
warning("Some items were negatively correlated with total scale and were automatically reversed.\n This is indicated by a negative sign for the variable name.")
keys <- 1 - 2 * (p1$loadings < 0)
}
else {
warning("Some items were negatively correlated with the total scale and probably should be reversed. To do this, run the function again with the 'check.keys=TRUE' option")
cat("Some items (", rownames(p1$loadings)[(p1$loadings < 0)], ") were negatively correlated with the total scale and probably should be reversed. To do this, run the function again with the 'check.keys=TRUE' option")
}
}`
thanks!
The culprit here is cat, which will not heed suppressMessages etc.
To catch it, you can use capture.output instead:
invisible(capture.output(alpha(data, na.rm=F, check.keys=F, delete=F)))
capture.output calls sink(…, type = "output") internally and discards/returns the result.
This is a follow-up to removeSource() returning error on internal package function.
In that question, it was pointed out that there may be a bug in removeSource() when the function uses [ subsetting. I want to focus on that issue, so I wrote a new question here.
When the j argument in [ is empty, removeSource() fails.
Here's an example.
foo <- function(x) { x[1, ] }
removeSource(foo)
# Error in recurse(part[[i]]) : argument "part" is missing, with no default
bar <- function(x) { x[1, seq_along(x)] }
removeSource(bar)
# function (x)
# {
# x[1, seq_along(x)]
# }
I'm hesitant to call it a bug, so I'll first ask if this was done intentionally? Also, suppose I submitted the foo() function in a package to CRAN. Would it pass the testing?
Updates:
Sept 1, 2014: Bug report filed https://bugs.r-project.org/bugzilla/show_bug.cgi?id=15957
Sept 21, 2014: This was indeed a bug and according to the confirmed bug report is "soon to be fixed in R-devel and R-patched."
Fixed in version R 3.1.2
I'd say it was a bug. No sign of it reported here though:
https://bugs.r-project.org/bugzilla3/buglist.cgi?quicksearch=removeSource
Interestingly you get a different error once you try and debug the function by making a local copy.
> dput(removeSource,file="rs.tmp.R")
> rs = dget("rs.tmp.R")
rs is now a copy of removeSource, but not in the environment of the utils package.
> foo = function(x){x[1,]}
> rs(foo)
Error in `attr<-`(`*tmp*`, "srcref", value = NULL) : '*tmp*' is missing
> removeSource(foo)
Error in recurse(part[[i]]) : argument "part" is missing, with no default
rs works fine on a function without missing subs:
> bar = function(x){x[1]}
> rs(bar)
function (x)
{
x[1]
}
If you want a really minimal failing example, you don't need any subscripts or commas:
> foo = function(x){x[]}
> removeSource(foo)
Error in recurse(part[[i]]) : argument "part" is missing, with no default
I doubt this will trigger any CRAN flags since missing dimensions in subscripts probably occur in 90% of the packages currently on there...
Suggest you report it on the bug tracker, or ask on R-devel mailing list.