【问题标题】:Multinomial Summary output to dataframe in R多项摘要输出到R中的数据框
【发布时间】:2021-11-09 19:46:21
【问题描述】:

我在下面创建了一个多项逻辑回归:

我已将系数、标准误差、z 统计量和 p 值存储在不同的变量中。 我正在尝试创建一个数据框来存储所有这些信息。

library(foreign)
library(nnet)
ml <- read.dta("https://stats.idre.ucla.edu/stat/data/hsbdemo.dta")
ml$prog2 <- relevel(ml$prog, ref = "academic")
test <- multinom(prog2 ~ 1, data = ml)

coeff <- summary(test)$coefficients
std.errs <- summary(test)$standard.errors

# calculate z-statistics of coefficients
z_stats <- summary(test)$coefficients/
  summary(test)$standard.errors

# convert to p-values
p_values <- (1 - pnorm(abs(z_stats)))*2

> std.errs
         (Intercept)
general    0.1781742
vocation   0.1718249
> coeff
         (Intercept)
general   -0.8472980
vocation  -0.7419374
> p_values
          (Intercept)
general  1.980067e-06
vocation 1.574605e-05
> z_stats
         (Intercept)
general    -4.755448
vocation   -4.317984

这是我的预期输出。如何从我创建的变量创建这个数据框?我在使用 (Intercept) 列创建 general_intercept 时遇到问题。我希望通过 dplyr 来完成。

feature             coefficient std.error  pval z.stat
general_intercept   -0.8472980  0.1781742  1.980067e-06  -4.755448       
vocation_intercept  -0.7419374  0.1718249  1.574605e-05 -4.317984
         

我需要它对变量的数量也是动态的。 例如,如果我运行这个多项逻辑回归

multinom(prog ~ ses + write, data=mdata)

我会得到这个表结构:

feature             coefficient  std.error p.val z_stat
academic_intercept         
academic_sesmiddle              
academic_seshigh
vocation_intercept 
vocation_sesmiddle
vocation_seshigh

【问题讨论】:

    标签: r


    【解决方案1】:
    df <- cbind(coeff, std.errs, p_values, z_stats)
    colnames(df) <- c("coefficient", "SE", "p_val", "z_stat")
    
             coefficient        SE        p_val    z_stat
    general   -0.8472980 0.1781742 1.980067e-06 -4.755448
    vocation  -0.7419374 0.1718249 1.574605e-05 -4.317984
    

    如果要重命名行索引:

    rownames(df) <- c("general_intercept", "vocation_intercept")
    
                       coefficient        SE        p_val    z_stat
    general_intercept   -0.8472980 0.1781742 1.980067e-06 -4.755448
    vocation_intercept  -0.7419374 0.1718249 1.574605e-05 -4.317984
    

    要动态更改行名,您可以:

    rownames(df) <- paste(rownames(df), tolower(gsub("[^a-zA-Z]", "", colnames(coeff))), sep = "_")
    
                       coefficient        SE        p_val    z_stat
    general_intercept   -0.8472980 0.1781742 1.980067e-06 -4.755448
    vocation_intercept  -0.7419374 0.1718249 1.574605e-05 -4.317984
    

    编辑:有了新的要求,我们可以编写一个可以做到这一点的函数。这有点单一,可能会分成几个功能。请注意,为了使其工作,对象必须作为命名列表传入。编写此函数是为了使用您已经定义的各种统计信息。 coeff &lt;- summary(test)$coefficients。除了你使用的包外,还需要reshape2dplyr

    create_summary = function(stats) {
      if (!is.list(stats)) {
        stop("Argument must be a named list")
      }
      df = NULL
      for (i in 1:length(stats)) {
        stat = as.data.frame(stats[[i]])
        stat$feature = rownames(stat)
        stat = stat %>%
          melt(id.vars = c("feature")) %>%
          mutate(feature = paste(feature,
                                 tolower(gsub(pattern = "[^a-zA-Z]",
                                              replacement = "",
                                              variable)),
                                 sep = "_")) %>%
          select(feature, value)
    
        colnames(stat) = c("feature", names(stats)[i])
        if (is.null(df)) {
          df = stat
        } else {
          df = merge(df, stat, by = "feature")
        }
      }
      return(df)
    }
    

    用初始模型test &lt;- multinom(prog2 ~ 1, data=ml)

    create_summary((list(coefficients = coeff,
                         se = std.errs,
                         p_val = p_values,
                         z_stat = z_stats)))
    
                 feature coefficients        se        p_val    z_stat
    1  general_intercept   -0.8472980 0.1781742 1.980067e-06 -4.755448
    2 vocation_intercept   -0.7419374 0.1718249 1.574605e-05 -4.317984
    

    使用您的第二个模型test &lt;- multinom(prog ~ ses + write, data=ml)

                 feature coefficients         se      p_val     z_stat
    1 academic_intercept  -2.85197258 1.16643741 0.01448407 -2.4450284
    2   academic_seshigh   1.16282574 0.51422150 0.02373868  2.2613324
    3 academic_sesmiddle   0.53329140 0.44373191 0.22942845  1.2018324
    4     academic_write   0.05792480 0.02141092 0.00682251  2.7053858
    5 vocation_intercept   2.36609732 1.17425127 0.04390634  2.0149838
    6   vocation_seshigh   0.18021764 0.64845085 0.78107356  0.2779203
    7 vocation_sesmiddle   0.82463840 0.49012366 0.09246981  1.6825109
    8     vocation_write  -0.05567514 0.02333135 0.01701977 -2.3862803
    

    您可以继续添加功能,摘要的长度会增加。

    【讨论】:

    • 感谢您提供此解决方案。你有一个使用 dplyr 的,还有一个动态的,用户不必手动指定行名?
    • 当您动态地说时,您是否只想将_intercept 附加到行名的末尾?如果不是,行名从何而来?
    • 列名是什么。在这种情况下,(截距)是唯一的列,因为我正在拟合仅截距模型。如果我适合给定其他功能,则会有更多功能列。
    • 嘿,我刚刚更新了我的问题。这行得通,但它对适合的功能数量不是动态的。例如,如果我向模型添加了另一个变量。 colnames(df) 中断。
    • @Eisen 啊,我想我知道你现在在找什么了。见编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多