Get environment of function from within the function
Ok, found the solution:
e$f <- function() unlockBinding("b", parent.env(environment()))
should do the trick.
changing functions and unlocking bindings in R
If you want, you can use the godmode
package from Github:
# save original version
orig <- graphics::boxplot.default
# devtools::install_github("miraisolutions/godmode")
godmode:::assignAnywhere("boxplot.default", boxplot.default_new)
# switch back
godmode:::assignAnywhere("boxplot.default", orig)
boxplot.default_new
should then be your re-write of boxplot.default
, possibly including your function myboxplot.stats
(maybe even rename it) and the call to it.
Problems with unlocking binding (in R) after running code from c++
Just received a solution from my professor:
"Instead of treating weights and trace as global variables that are modified from inside the batch function, we can pass them into the function and return them out:"
batch <- function(weights, trace, n.training){
for(i in 1:n.training){
g <- input.correlation()
for(o in 1:nrow(g)){
result <- traceUpdate(g[o,], trace, weights, trace.param, learning.rate)
weights <- result$weights
trace <- result$trace
}
}
return(list(weights=weights, trace=trace))
}
result <- batch(weights, trace, 50)
weights <- result$weights
trace <- result$trace
Capturing the global environment
This function avoids the side effects as much as possible:
library(ggplot2)
library(magrittr)
library(tibble)
my.better.plot <- function(){
x.coords <- 1
y.coords <- 1
environment(package.plot) <- environment()
bmp(tempfile())
package.plot()
dev.off()
print(tibble(x.coords,y.coords) %>% ggplot(aes(x=x.coords,y=y.coords))+geom_point()) # etc.
}
my.better.plot()
#creates only the ggplot in the current device
ls(globalenv())
#[1] "my.better.plot" "package.plot" "the.data"
Assigning a locked variable in an R package
Mostly not answering your question. I agree with @IShouldByABoat that there's more going on, a package with the simple structure you indicate doesn't generate the error you see for me. Likely you're trying to modify True elsewhere in your code (!) or perhaps you've got some cruft in your .Rprofile or .RData file that is interfering -- run your check as R --vanilla CMD check
.
Functions and symbols are defined in a package name space, for instance
library(plyr) ## load package name space, attach to the search() path
getNamespace(plyr) ## package name space
ls(getNamespace(plyr)) ## symbols defined in the name space
plyr::llply ## definition of `llply` in the name space
The package name space is locked after it has been loaded
assign("llply", identity, envir=getNamespace("plyr"))
## Error in assign("llply", identity, envir = getNamespace("plyr")) :
## cannot change value of locked binding for 'llply'
Assigning to a similarly named variable at the command line creates a new variable in the .GlobalEnv
(the first location on the search() path) rather than modifying the variable in the package name space
ls() ## no symbol 'llply' in .GlobalEnv
llply <- identity ## new symbol 'llply' in .GlobalEnv
llply(10) ## use first llply function in search(), i.e., in .GlobalEnv
plyr::llply(10) ## circumvent search path and use llply from plyr name space
So code such as
True <- TRUE
lockBinding("True", environment())
only adds a locked binding from the time True is created until the package is loaded; after that the binding is locked anyway.
Maybe you want to create a variable True in the user's .GlobalEnv, and make that so that it cannot be changed. This has to be done when the package is load'ed (or attach'ed), when the user's current .GlobalEnv is visible, with something like
.onAttach <- function(...) {
assign("True", TRUE, .GlobalEnv)
lockBinding("True", .GlobalEnv)
}
This only locks the binding in the .GlobalEnv so it cannot be changed, but does not stop the user from removing it (e.g., using rm("True")
). Messing with your user's .GlobalEnv will likely also serve to irritate your user more than further your programming agenda.
How to modify unexported object in a package
As it turns out, I only had to remove the unlockBinding
, assign
and lockBinding
calls.
bar <- function(x) x + 1
assignInNamespace("C_rf", bar, ns="stats", pos="package:stats")
stats:::C_rf
# function(x) x + 1
rf(3, 2, 2)
#Error in .Call(C_rf, n, df1, df2) :
# first argument must be a string (of length 1) or native symbol reference
Related Topics
Changes in Plotting an Xts Object
How to Convert Class of Several Variables at Once
Stargazer Output Appears Below Text - Rmarkdown to PDF
How to Render Custom Map Tiles Created with Gdal2Tiles in Leaflet for R
"Dims [Product Xx] Do Not Match the Length of Object [Xx]" Error in Using R Function 'Outer'
Tls V1.1/Tls V1.2 Support in Rcurl
Out of Order Text Labels on Stack Bar Plot (Ggplot)
Looping Over Combinations of Regression Model Terms
Why Does Nls Function Not Work in Ggplot2
Align Points and Error Bars in Ggplot When Using 'Jitterdodge'
Compare Two Columns Element-Wise
Selecting Unique Rows in Matrix Using R
R: Using "Microbenchmark" and Ggplot2 to Plot Runtimes
R Function That Uses Its Output as Its Own Input Repeatedly
Extracting HTML Table from a Website in R
Take the Subsets of a Data.Frame with the Same Feature and Select a Single Row from Each Subset