Search code examples
rfunctionglobal-variables

Output selected variables to global environment R function


I have function which is an extension of an earlier question here

Function to calculate median by column to an R dataframe that is done regularly to multiple dataframes

my function below

library(outliers)
MscoreMax <- 3

scores_na <- function(x, ...) {
  not_na <- !is.na(x)
  scores <- rep(NA, length(x))
  scores[not_na] <- outliers::scores(na.omit(x), ...)
  scores
}


mediansFunction <- function(x){
  labmedians <- sapply(x[-1], median)
  median_of_median <- median(labmedians)
  grand_median <- median(as.matrix(x[-1]))
  labMscore <- as.vector(round(abs(scores_na(labmedians, "mad")), digits = 2)) #calculate mscore by lab
  labMscoreIndex <- which(labMscore > MscoreMax) #get the position in the vector that exceeds Mscoremax
  x[-1][labMscoreIndex] <- NA # discharge values above threshold by making NA
  
     
       return(x) 
}


the function has the desired outcome of converting my Mscore values above the threshold to NA. However, I would like to send

  • labmedians
  • grand_median
  • labMscore

As their own variables to the global environment from within the function, but not as a list of items as 3 variables. Can i do this or is better to create a second function which is slightly different that sends the variables to the global environment as a function then use list2env outside the function afterwards to extract the variables as seperate items?

my df below

structure(list(Determination_No = 1:6, `2` = c(0.08, 0.08, 0.08, 
0.08, 0.08, 0.08), `3` = c(0.08, 0.07, 0.07, 0.08, 0.07, 0.07
), `4` = c(0.07, 0.08, 0.08, 0.08, 0.07, 0.08), `5` = c(0.08, 
0.08, 0.08, 0.08, 0.09, 0.09), `7` = c(0.09, 0.09, 0.11, 0.1, 
0.1, 0.1), `8` = c(0.086, 0.087, 0.086, 0.09, 0.083, 0.079), 
    `10` = c(0.049748274, 0.049748274, 0.066331032, 0.066331032, 
    0.066331032, 0.049748274), `12` = c(0.086, 0.078, 0.078, 
    0.077, 0.077, 0.068)), class = "data.frame", row.names = c(NA, 
-6L))



Solution

  • It is not recommended to write to global environment from inside the function. If you want to create multiple objects in the global environment return a named list from the function and use list2env.

    mediansFunction <- function(x){
      labmedians <- sapply(x[-1], median)
      median_of_median <- median(labmedians)
      grand_median <- median(as.matrix(x[-1]))
      labMscore <- as.vector(round(abs(scores_na(labmedians, "mad")), digits = 2)) #calculate mscore by lab
      labMscoreIndex <- which(labMscore > MscoreMax) #get the position in the vector that exceeds Mscoremax
      x[-1][labMscoreIndex] <- NA # discharge values above threshold by making NA
      dplyr::lst(data = x, labmedians, grand_median, labMscore)
    }
    
    result <- mediansFunction(df)
    list2env(result, .GlobalEnv)
    

    Now you have variables data, labmedians, grand_median and labMscore in the global environment.