Reputation: 2900
This is confusing me, so I hope I can explain it well...
I have created an R-package, and within that package I have 3 scripts (toy examples are below). 1 of the scripts generates some data/calculations and the remaining 2 scripts contain different plotting functions. For example, the scripts in my package look something like this...
The 1st script genData.R
creates a matrix of values, does a calculation and returns a data frame:
# Matrix Funtion with rows = r and columns = c:
xMat <- function(r, c){
Mat <- matrix(runif(r*c, 0, 1), nrow=r)
Mat <- Mat * 10
colnames(Mat) <- paste0("x", 1:c)
df <- data.frame(Mat)
df
}
The remaining scripts are similar to each other, the only difference between them is the type of plot they produce. They both contain a call to xMat()
to generate the data and then plot the data using a separate plotting function. The 1st plotting script plot1.R
looks like so:
#' @param r no of rows
#' @param c no of cols
#' @import ggplot2
#' @export
xFunc <- function(r,c){
Val <- xMat(r,c)
xPlot(Val)
}
xPlot <- function(df){
myData <- df
p <- ggplot(myData, aes(x1, x2)) +
geom_tile(aes(fill = x1))
p
}
And similarly, the 2nd plotting function plot2.R
script looks like so:
#' @param r no of rows
#' @param c no of cols
#' @import ggplot2
#' @import reshape
#' @export
xFunc.1 <- function(r,c){
Val <- xMat(r,c)
xPlot.1(Val)
}
xPlot.1 <- function(df){
myData <- df
df <- melt(df)
p <-ggplot(df, aes(x = df$variable, y = df$value)) + geom_line()
p
}
What im trying to do is, if, say, I called the function xFunc()
first, then it will call xMat()
to generate the data etc.... but then afterwards, if I call xFunc.1
, I don't want it to call xMat
again and have to generate new data.
I want to be able to store the object df
created by xMat
and then when I call xFunc.1
it just retrieves the object df
instead of having to do the data generation/calculations again. I have edited this question to reflect that I cannot store the object df
in the global environment. CRAN do not allow modifications to the users environment. I have been experimenting with creating a local environment within the package using new.env()
, but I'm not sure how to make this work?
I imagine it might look something like this:
if(xMat has not previously been run){
execute xMat
}else{
If xMat has been run then
retrieve the df object previously created by xMat
}
I hope I explained that clearly.... Any suggestions as to how I would do this?
Upvotes: 0
Views: 66
Reputation: 2143
I'm assuming you're running these scripts in arbitrary order, and you're not restarting R. You could
if(! exists("myXMatDf")){
myXMatDf <- xMat(r,c)}
But that gets error-prone if you forget which values of r
and c
you last used.
If you want to save rerunning xMat
even when you've, say, rebooted your machine, you can write to a cache.
if(file.exists("cache/myXMatDf.RData"){
load("cache/myXMatDf.RData")
} else {
myXMatDf <- xMat(r,c)
save(myXMatDf, r, c, file = "cache/myXMatDf.RData"
}
# NOT RUN #
P.S. on exists
:
R > y
Error: object 'y' not found
R > exists("y")
[1] FALSE
R > y <- 8
R > y
[1] 8
R > exists("y")
[1] TRUE
exists
takes a string. It tests whether there's anything in the environment by that name. Before you run your script the first time, myXMatDf
isn't bound - it doesn't have a value. exists("myXMatDf")
is FALSE. After you run your script myXMatDf
is bound to a data frame. exists("myXMatDf")
is TRUE.
Upvotes: 1