【问题标题】:R - passing object to function based on the NAME of the objectR - 根据对象的名称将对象传递给函数
【发布时间】:2020-08-25 11:00:29
【问题描述】:

假设在 R 中我有来自多个 glm() 函数调用的多个 GLM 对象。

glm_01
glm_02
...
glm_nn

...假设我想使用卡方或 F ANOVA 检验进行所有可能的成对比较。

anova(glm_01, glm_02, test = "F")
anova(glm_01, glm_03, test = "F")
anova(glm_01, glm_04, test = "F")
...

我不想手动执行此操作,因为模型列表很长。相反,我想获取相关模型对象的列表(以"glm_" 开头的任何内容)并自动进行所有成对比较。但是我不确定如何将模型对象(而不是字符串形式的名称)传递给 anova() 函数。

举个简单的例子:

data(mtcars)

# create some models

glm_01 <- glm(mpg ~ cyl                 , mtcars, family = gaussian())
glm_02 <- glm(mpg ~ cyl + disp          , mtcars, family = gaussian())
glm_03 <- glm(mpg ~ cyl + disp + hp     , mtcars, family = gaussian())
glm_04 <- glm(mpg ~ cyl + disp + hp + wt, mtcars, family = gaussian())

# get list of relevant model objects from the R environment

model_list <- ls()
model_list <- model_list[substr(model_list, 1, 4) == "glm_"]

# create a table to store the pairwise ANOVA results

n_models <- length(model_list)
anova_table <- matrix(0, nrow = n_models, ncol = n_models)

# loop through twice and do pairwise comparisons

for(row_index in 1:n_models) {
  for(col_index in 1:n_models) {
      anova_table[row_index, col_index] <- anova(model_list[row_index], model_list[col_index], test = "F")$'Pr(>F)'[2]
  }
}

...但是最后这个循环当然不起作用,因为我没有将模型对象传递给anova(),而是将对象的名称作为字符串传递。如何告诉anova() 使用字符串引用的对象,而不是字符串本身?

谢谢。

=======================

可能的解决方案:

data(mtcars)

glm_list <- list()

glm_list$glm_01 <- glm(mpg ~ cyl                 , mtcars, family = gaussian())
glm_list$glm_02 <- glm(mpg ~ cyl + disp          , mtcars, family = gaussian())
glm_list$glm_03 <- glm(mpg ~ cyl + disp + hp     , mtcars, family = gaussian())
glm_list$glm_04 <- glm(mpg ~ cyl + disp + hp + wt, mtcars, family = gaussian())

# create a table to store the pairwise ANOVA results

n_models <- length(glm_list)
anova_table <- matrix(0, nrow = n_models, ncol = n_models)

# loop through twice and do pairwise comparisons

row_idx <- 0
col_idx <- 0

for(row_glm in glm_list)
{
  row_idx <- row_idx + 1
  
  for(col_glm in glm_list)
  {
    col_idx <- col_idx + 1
    anova_table[row_idx, col_idx] <- anova(row_glm, col_glm, test = "F")$'Pr(>F)'[2]
  }
  col_idx <- 0
}
row_idx <- 0

【问题讨论】:

  • 如果您只是将所有模型放在一个列表中开始,这会容易得多。然后,您可以使用列表索引对它们进行迭代。
  • 哦……我没想到。玩过代码并编辑了我的帖子以显示可能的解决方案(有点笨拙但似乎有效)。谢谢。

标签: r glm anova


【解决方案1】:

最简单的方法是将所有模型保存在一个列表中。这使得迭代它们变得简单。例如,您可以创建所有模型并在所有模型之间进行成对比较,如下所示:

data(mtcars)

f_list <- list(mpg ~ cyl, 
               mpg ~ cyl + disp,
               mpg ~ cyl + disp + hp,
               mpg ~ cyl + disp + hp + wt)

all_glms  <- lapply(f_list, glm, data = mtcars, family = gaussian)
all_pairs <- as.data.frame(combn(length(all_glms), 2))
result <- lapply(all_pairs, function(i) anova(all_glms[[i[1]]], all_glms[[i[2]]]))

这给了你:

result
#> $V1
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl
#> Model 2: mpg ~ cyl + disp
#>   Resid. Df Resid. Dev Df Deviance
#> 1        30     308.33            
#> 2        29     270.74  1   37.594
#> 
#> $V2
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl
#> Model 2: mpg ~ cyl + disp + hp
#>   Resid. Df Resid. Dev Df Deviance
#> 1        30     308.33            
#> 2        28     261.37  2   46.965
#> 
#> $V3
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl
#> Model 2: mpg ~ cyl + disp + hp + wt
#>   Resid. Df Resid. Dev Df Deviance
#> 1        30     308.33            
#> 2        27     170.44  3   137.89
#> 
#> $V4
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl + disp
#> Model 2: mpg ~ cyl + disp + hp
#>   Resid. Df Resid. Dev Df Deviance
#> 1        29     270.74            
#> 2        28     261.37  1   9.3709
#> 
#> $V5
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl + disp
#> Model 2: mpg ~ cyl + disp + hp + wt
#>   Resid. Df Resid. Dev Df Deviance
#> 1        29     270.74            
#> 2        27     170.44  2    100.3
#> 
#> $V6
#> Analysis of Deviance Table
#> 
#> Model 1: mpg ~ cyl + disp + hp
#> Model 2: mpg ~ cyl + disp + hp + wt
#>   Resid. Df Resid. Dev Df Deviance
#> 1        28     261.37            
#> 2        27     170.44  1   90.925

reprex package (v0.3.0) 于 2020 年 8 月 25 日创建

【讨论】:

  • 谢谢。我自己做了一些事情(当我看到你的第一条评论时),但它不如你的优雅(我不太擅长在 R 中使用 *apply!)。
【解决方案2】:

如果您想通过符号引用可访问环境中的任意对象而不将它们放入列表对象中,则返回搜索列表中符号等于字符串的顶部对象的标准方法是get(),或者向量等效mget()。 IE。 get("glm_01") 为您提供搜索列表中具有符号 glm_01 的顶部对象。对您的方法的最小修改是将您对model_list[row_index]model_list[col_index] 的调用封装在get() 中。

您可以通过在命名环境中分配模型并且仅在该环境中分配模型getting(使用envir 参数到get())来更精确地查找对象的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    相关资源
    最近更新 更多