简体   繁体   中英

Changing names of list elements for several lists

I would like to manipulate a named vector within a list, and do that for a large number of similarly named lists. Specifically, my lists are results from glm , and I want to change the names of the coefficients list element.

Here's a toy example:

model_1 <- glm(Petal.Width ~ Sepal.Length*Sepal.Width, data = iris)
model_2 <- glm(Petal.Length ~ Sepal.Length*Sepal.Width, data = iris)

The desired manipulation for one list:

names(model_1$coefficients) <- c("Constant", "Length", "Width", "Length * Width")

Now trying to do this for both lists:

for (i in 1:2) {
  list_name <- paste("model", i, sep = ""),
  names(list_name$coefficients) <- c("Constant", "Length", "Width", "Length * Width")
 }

But of course, this does not work because R tries to evaluate a list called "list_name". How could I make it evaluate the list named as the variable "list_name"?

While both previous answers include valid solutions to your specific problem, I would strongly suggest to use a list as a container for all your models, as this would make the overall handling of them much easier.

models <- list()
models$m_1 <- glm(Petal.Width ~ Sepal.Length*Sepal.Width, data = iris)
models$m_2 <- glm(Petal.Length ~ Sepal.Length*Sepal.Width, data = iris)

coefNames <- c("Constant", "Length", "Width", "Length * Width")

models <- lapply(models, function(x) {
  names(x$coefficients) <- coefNames
  x })

Or in tidyverse :

models <- map(models, ~  { 
    .$coefficients <- set_names(.$coefficients, coefNames)
. })

Or, the simplest solution, with a for loop:

for(i in 1:length(models)) {
    names(models[[i]]$coefficients) <- coefNames
}

Or, say, you have a selection of models:

selmods <- paste0("m_", 1:2)
for(i in selmods) {
   names(models[[i]]$coefficients) <- coefNames
}

Use a combination of get and assign :

set_coef_names <- function(x) {
  names(x$coefficients) <- c("Constant", "Length", "Width", "Length * Width")
  return(x)
}

for (i in 1:2) {
  assign(paste("model_", i, sep = ""), set_coef_names(get(paste("model_", i, sep = ""))))
}

This can also be solved without assign() *:

lapply(
  mget(paste0("model_", 1:2)), 
  function(x) {
    names(x$coefficients) <- c("Constant", "Length", "Width", "Length * Width")
    x
  }
)
 $model_1 Call: glm(formula = Petal.Width ~ Sepal.Length * Sepal.Width, data = iris) Coefficients: Constant Length Width Length * Width 3.9532 -0.2490 -2.2488 0.3129 Degrees of Freedom: 149 Total (ie Null); 146 Residual Null Deviance: 86.57 Residual Deviance: 20.9 AIC: 140.1 $model_2 Call: glm(formula = Petal.Length ~ Sepal.Length * Sepal.Width, data = iris) Coefficients: Constant Length Width Length * Width 6.3910 0.2042 -4.1994 0.5057 Degrees of Freedom: 149 Total (ie Null); 146 Residual Null Deviance: 464.3 Residual Deviance: 57.91 AIC: 292.9 

mget() searches the environment for objects by name and returns a list of the objects. lapply() applies the function on each of the list elements and returns a list, again.


* There are many voices which recommend to avoid assign() , eg,

  • R FAQ
  • Why is using assign bad?
  • fortunes::fortune(236) : "The only people who should use the assign function are those who fully understand why you should never use the assign function." -- Greg Snow, R-help (July 2009)

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