Search code examples
ruser-defined-functionsrstudiorstudio-server

how to provide output of user-defined-function as data.frame in R in .GlobalEnv


I have created a function 'mywsobj' which takes one input & 2 output

user input: environment

output1: a data.frame name "wsobj" (data of list of objects,their classes,their memory usage) output to console output2: a barplot of list of objects and their memory usage based.

So far all ok,

My question1: but How to save that "wsobj" data.frame from inside the function in that user-specified input environment or at least in the .GlobalEnv ? I tried reading things like: use of <<, use of pos/parent.environment etc. but things are so far beyond me.

My question2: Is it possible to specify project-specific/user-specfic environment in R/specially in Rstudio server ?

Though my code here may not matter still it is below:

    # creating SOME data
dfAtoZ<- data.frame(LETTERS) 
df1to1Cr <- data.frame(1:10000000)
vec1to1Cr <- as.vector(1:10000000)
mat1to1Cr <- as.matrix(1:10000000)
set.seed<-10
randvec<-runif(1000,min=-100,max=100)
# creating MY function
mywsobj<-function(myenvironmentName)
{#step1 creating vector of object names
wslist <- vector(length=length(ls(myenvironmentName)))
for(i in 1:length(ls(myenvironmentName)))
{wslist[i]<-ls(myenvironmentName)[i]}
# wslist<-cbind(unlist(ls()))
#step2 creating vector of object classes
wsclass <- vector(length=length(wslist))
wsmemKb <- vector(mode="numeric",length=length(wslist))
for(i in 1:length(wslist))
{wsclass[i]<-class(get(wslist[i]))
wsmemKb[i]<- object.size(get(wslist[i]))/1000*1024}
#step4 combining them in a data.frame
wobj<-data.frame(cbind(wslist,wsclass,wsmemKb))
# library(sqldf)
# sqldf("pragma table_info(wobj)") shows col 3(wsmem) still non-numeric
wobj[,3] <- as.numeric( as.character(wobj[,3]) )
# create data to return matrix of memory consumption
objmemsize <- rev(sort(sapply(ls(envir=myenvironmentName), 
                function (object.name)object.size(get(object.name))/1000)))
# draw bar plot
barplot(objmemsize,main="Memory usage by object in myenvironment", 
          ylab="KiloByte", xlab="Variable name", 
            col=heat.colors(length(objmemsize)))
# result <- sqldf("select * from wobj order by 1/wsmemKb")
return(wobj)
#   return(data.frame(myenvironmentName,wobj))
#   return(assign("myname",wobj,envir = .GlobalEnv))
#   attach(wobj,pos=2,"wobj")
return(barplot)
}
# use of mywsobj function
mywsobj(.GlobalEnv)
# saving output of mywsobj function
output<-as.data.frame(mywsobj(.GlobalEnv))   

Solution

  • Not sure if this is what you're after. But, you can assign values to that environment with $.

    my_fun <- function(in.env) {
        # you may want to check if input argument is an environment
    
        # do your computations
        set.seed(45)
        x <- sample(10)
        y <- runif(10)
        in.env$val <- sum(x*y)
    }
    
    my_fun(my.env <- new.env())
    ls(my.env)
    [1] "val"
    my.env$val
    # [1] 22.30493
    

    Alternatively, you can also use assign as follows:

    my_fun <- function(in.env) {
        # you may want to check if input argument is an environment
    
        # do your computations
        set.seed(45)
        x <- sample(10)
        y <- runif(10)
        assign("val", sum(x*y), envir=in.env)
    }
    
    # assign to global environment
    my_fun(globalenv())
    > val
    # [1] 22.30493
    
    # assign to local environment, say, v
    v <- new.env()
    my_fun(v)
    > v$val
    # [1] 22.30493