简体   繁体   中英

Assign a dynamic function to Global Environment in R

This question will be a simple one for some members of this forum, but I am expending a lot of time searching for an answer and I did not find any working one. Let me clarify: I have a simple function that conducts a linear regression, and the results become a variable and this variable is assigned to the global environment. Straightforward method.

However, every time I run this function, the variable is replaced, what I don't want. I just want to define a specific name instead of replacing this variable.

Please check out this code to understand my question:

set.seed(123)
ds <- data.frame(income=rnorm(1000,700,20), sex=c(0,1), age=rnorm(1000,30,10))

regress <- function(iv_string) {
  regression_formula <- as.formula(paste("income ~", iv_string))
  results <<- lm(regression_formula, ds)
  plot(results)
  print(results)
}
regress("age")
regress("sex")

Something like that

  regress <- function(iv_string, **custom_name**) {
      regression_formula <- as.formula(paste("income ~", iv_string))
      results[**custom_name**] <<- lm(regression_formula, ds)
      plot(results)
      print(results)
    }
regress("sex","sex_on_income") #this model will be used in other analysis, once it will be assigned at global environment
regress("age","age_on_income") #this model will be used !!

最终解决方案 Thanks much.

This will write the lm object out to the parent frame or other environment specified by env , plot it, print it and invisibly return it. Also we make sure that the formula's environment is env which allows iv_string to refer to objects in env as well as columns in ds . (If we knew that iv_string only referred to column names in ds then we could just use fo <- paste("income ~", iv_string) as lm will accept character strings as formulas.) We use do.call(...) to ensure that the lm output shows the actual formula rather than just fo . We used the parent frame as the default for env which is more usual but if you really want the default to be the global environment replace parent.frame() with .GlobalEnv or with globalenv() .

regress <- function(iv_string, custom_name = iv_string, env = parent.frame()) {
  fo <- as.formula(paste("income ~", iv_string), env)
  env[[custom_name]] <- results <- do.call("lm", list(fo, quote(ds)))
  plot(results)
  print(results)
  invisible(results)
}

regress("age", "lm_age")

giving:

Call:
lm(formula = income ~ age, data = ds)  <-- note that formula shows, not just fo

Coefficients:
(Intercept)          age  
   695.1540       0.1699  

That said, the normal style in R is not to write objects out to the parent frame or to the global environment but to return them:

regress <- function(iv_string, env = parent.frame()) {
  fo <- as.formula(paste("income ~", iv_string), env)
  results <- do.call("lm", list(fo, quote(ds)))
  plot(results)
  print(results)
  invisible(results)
}

lm_age <- regress("age")

Here is a modified version of your code that I think gives you what you want.

regress <- function(iv_string, custom_name) {
  regression_formula <- as.formula(paste("income ~", iv_string))
  assign(custom_name, lm(regression_formula, ds), envir = .GlobalEnv)
  plot(get(custom_name))
  print(get(custom_name))
}

regress("age", "age_reg")

In the code above, I assign the regression results to a global variable defined by the string custom_name . For the plot and print statements, I use get to get the variable named in that string and pass it to those functions. So, in my example, it'll create the plots and print the results and a variable called age_reg will appear in the global environment and contain the regression results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM