【问题标题】:extracting standardized coefficients from lm in R从 R 中的 lm 中提取标准化系数
【发布时间】:2014-08-09 21:54:50
【问题描述】:

对于这个愚蠢的问题,我深表歉意……但我似乎找不到简单的解决方案

我想从拟合的线性模型中提取标准化系数(在 R 中) 必须有一种简单的方法或功能可以做到这一点。你能告诉我这是什么吗?

编辑(遵循下面的一些 cmets): 我可能应该提供有关我的问题的更多上下文信息。我正在为一群心理学家教授一个介绍性的 R 研讨会。对他们来说,一个无法获得标准化系数的线性模型就好像你根本没有运行这个模型(好吧,这有点夸张,但你明白了)。当我们做了一些回归时,这是他们的第一个问题,这(我的错)我没有预料到(我不是心理学家)。当然我可以自己编程,当然我可以寻找为我做这件事的包。但同时,我确实认为这是线性模型的一种基本且常见的必需功能,当场我认为应该有一个基本功能可以做到这一点,而无需安装越来越多的包(这被认为是初学者的困难)。所以我问了(这也是向他们展示如何在需要帮助时获得帮助的机会)。

对于那些认为我问了一个愚蠢的问题的人,我深表歉意,非常感谢那些花时间回答它的人。

【问题讨论】:

  • 试试这个函数stdcoeff <- function (MOD) {b <- summary(MOD)$coef[-1, 1] ; sx <- sd(MOD$model[-1]); sy <- sd(MOD$model[1]); beta <- b * sx/sy ; return(beta) },其中MOD是你的模型,由lm函数生成,所以你将它用作stdcoeff(lm(...))(我没有写,只是在网络,所以不作为答案发布)
  • 我喜欢this approach。它将输入变量重新调整为标准偏差的两倍,以便于解释。它的standardize函数可以在arm包中找到。
  • @CarlWitthoft,您在帮助文件中哪里可以看到这个问题的解决方案? @DavidArenburg 的评论或下面的 QuantPsyc::lm.beta 答案是否正确取决于 OP 所指的“标准化”(他们没有具体说明)
  • 哎呀,我对“几个定义”实际上是错误的——抱歉。我太快地阅读了@DavidArenburg 的评论(并且不记得lm 将模型框架存储在那里);他的注释与QuantPsyc::lm.beta中的内部代码相同
  • whut evvarrr.. 抱歉在这里发牢骚。

标签: r regression lm beta standardized


【解决方案1】:

lm.beta 有几个函数可以处理标准化系数,包括需要lm 对象的lm.beta()

res <- lm(y~x)
lm.beta(res) 

【讨论】:

    【解决方案2】:

    只需将colnames(data)lapplysapply 一起使用。
    例如:

    lapply(data[, colnames(data)], scale)
    

    【讨论】:

    • 如果您的任何输入不是标量,这将非常不方便。
    【解决方案3】:

    QuantPsyc 包中有一个方便的函数,称为lm.beta。但是,我认为最简单的方法是标准化您的变量。然后,这些系数将自动成为标准化的“beta”系数(即标准偏差方面的系数)。

    例如,

     lm(scale(your.y) ~ scale(your.x), data=your.Data)
    

    会给你标准化的系数。

    它们真的一样吗?以下说明两者是相同的:

    library("QuantPsyc")
    mod <- lm(weight ~ height, data=women)
    coef_lmbeta <- lm.beta(mod)
    
    coef_lmbeta
    > height 
      0.9955 
    
    mod2 <- lm(scale(weight) ~ scale(height), data=women)
    coef_scale <- coef(mod2)[2]
    
    coef_scale
    > scale(height) 
      0.9955 
    
    all.equal(coef_lmbeta, coef_scale, check.attributes=F)
    [1] TRUE
    

    这表明两者应该是相同的。

    如何避免笨拙的变量名? 如果您不想处理这些笨拙的变量名称,例如scale(height),一种选择是在数据集本身中对lm 调用之外的变量进行标准化。例如,

    women2 <- lapply(women, scale) # standardizes all variables
    
    mod3 <- lm(weight ~ height, data=women2)
    coef_alt <- coef(mod3)[2]
    coef_alt
    > height 
      0.9955 
    
    all.equal(coef_lmbeta, coef_alt)
    [1] TRUE
    

    如何方便地标准化多个变量?如果您不想标准化数据集中的所有变量,您可以选择公式中出现的所有变量。比如现在引用mtcars-dataset(因为women只包含heightweight):

    说下面是我要估计的回归模型:

     modelformula <- mpg ~ cyl + disp + hp + drat + qsec
    

    我们可以利用all.vars 给我一个变量名向量这一事实。

     all.vars(modelformula)
     [1] "mpg"  "cyl"  "disp" "hp"   "drat" "qsec"
    

    我们可以使用它来相应地对数据集进行子集化。例如,

    mycars <- lapply(mtcars[, all.vars(modelformula)], scale) 
    

    会给我一个所有变量都已标准化的数据集。使用 mycars 的线性回归现在将给出标准化的 beta。不过,请确保对所有这些变量进行标准化是有意义的!

    只有一个变量的潜在问题:如果您的模型公式仅包含一个解释变量并且您正在使用内置数据框(而不是小标题),建议进行以下调整(学分转到 cmets 中的@JerryT):

    mycars <- lapply(mtcars[, all.vars(modelformula), drop=F], scale) 
    

    这是因为当您从标准数据帧中仅提取一列时,R 会重新调整向量而不是数据帧。 drop=F 将防止这种情况发生。如果例如,这也不会成为问题。使用tibbles。参见例如

    class(mtcars[, "mpg"])
    [1] "numeric"
    class(mtcars[, "mpg", drop=F])
    [1] "data.frame"
    library(tidyverse)
    class(as.tibble(mtcars)[, "mpg"])
    [1] "tbl_df"     "tbl"        "data.frame"
    

    数据框中缺少值的另一个问题(信用再次转到 cmets 中的 @JerryT):默认情况下,R 的 lm 删除所有 ,其中至少缺少一列。另一方面,scale 将采用所有非缺失值,即使观察值在不同列中有缺失值。如果您想模仿lm 的操作,您可能需要先删除所有缺失值的行,如下所示:

    all_complete <- complete.cases(df)
    df[all_complete,]
    

    【讨论】:

    • 请注意,这或多或少是 arm::standardize 所做的(尽管它提供了一些关于响应是否缩放的灵活性,并且为分类预测器做了一些更花哨/非标准的东西)。 lm.beta 方法的优点是不需要重新拟合模型。
    • 标准化多个变量的dplyr 替代方案是:mycars &lt;- mtcars %&gt;% mutate_each_(funs(scale), all.vars(model.formula)),我相信。
    • 确保在 scale 之前删除 na(如果缺少), lapply(mtcars[, all.vars(modelformula), drop=F], scale) 以防只有一个变量modelformula 还有一个 lm.beta 包也可以做到这一点
    • @coffeinjunky 您在这里是一位非常出色的老师,并且很好地解释了事情。我认为 lapply 按列应用比例,例如,cyl 在第 1 行有 NA,disp 在第 2 行有 NA。当一个人做 lm 时,第 1 行和第 2 行都将由于 NA 而被删除,但 scale 只会删除第 1 行cyl,第 2 行用于显示。所以我认为最好在 scale 之前做 drop na,与 lm 的 na.action 保持一致(假设 na.exclude 或 na.omit)
    • @JerryT 公平点。没想到!感谢您的解释。稍后会更新!
    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2020-06-05
    • 2018-09-11
    • 2016-11-15
    • 2018-02-07
    • 2013-05-13
    相关资源
    最近更新 更多