【问题标题】:Extracting P-value column from output Anova (car package)从输出 Anova(汽车包)中提取 P 值列
【发布时间】:2020-12-05 20:24:41
【问题描述】:

我正在使用“汽车”包函数 Anova 进行一些统计测试。

它给出以下输出:

    Y = cbind(curdata$V1, curdata$V2, curdata$V3)
    mymdl = lm(Y ~ curdata$V4 + curdata$V5)
    myanova = Anova(mymdl)
    
Type II MANOVA Tests: Pillai test statistic
           Df test stat approx F num Df den Df  Pr(>F)  
curdata$V4  1   0.27941   2.9728      3     23 0.05280 .
curdata$V5  1   0.33570   3.8743      3     23 0.02228 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

我想提取 'Pr(>F)' 列中的值,因此我可以将这些 p 值放在另一个矩阵中,以便以后更正多重比较。

我尝试过使用 unlist,但它仍然没有提供在列中找到的 p 值。

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: r anova


    【解决方案1】:

    如果我们有多个响应变量,则为Manova。我们可以捕获输出并使用正则表达式

    as.numeric(sub(".*\\s*(\\d+\\.[0-9e-]+)\\s*[*.]*", "\\1", capture.output(out)[4:5]))
    #[1] 8.836e-06 2.200e-16
    

    数据

     mymdl <- lm(cbind(Sepal.Length, Sepal.Width) ~ Petal.Width + 
         Petal.Length, data = iris)
    
     out <- Anova(mymdl)
    

    【讨论】:

    • 亲爱的 Akrun,我已经尝试过了,但它会产生 NULL 输出。知道我可能做错了什么吗?
    • @pdhami 你用过Anova 还是Manova
    • 亲爱的 akrun,我使用了 Anova。
    • @pdhami 抱歉,你能试试正则表达式解决方案吗
    • @pdhami 能不能把代码修改成as.numeric(sub(".*\\s*(\\d+\\.[0-9e-]+)\\s*[*.]*", "\\1", capture.output(out)[4:5]))
    【解决方案2】:

    也许不是最实用的方法,但您可以使用来自tidyrseparate() 来玩转列:

    library(car)
    library(dplyr)
    library(tidyr)
    #Code
    v1 <- data.frame(capture.output(myanova))
    v1 <- v1[3:5,,drop=F]
    names(v1)<-'v1'
    v2 <- separate(v1,v1,c(paste0('v',1:21)),sep = '\\s')
    v2 <- v2[-1,]
    

    输出:

    as.numeric(v2$v21)
    [1] 8.836e-06 2.200e-16
    

    警告:如果捕获操作中存在更多列,则需要在必要时更改 1:21

    【讨论】:

    • 谢谢!该解决方案还提供了所需的输出。
    【解决方案3】:

    TLDR:

    # define helper:
    get_summary_for_print <- car:::print.Anova.mlm
    body(get_summary_for_print) <- local({tmp <- body(get_summary_for_print);tmp[-(length(tmp)-(0:1))]})
    #use it:
    get_summary_for_print(Anova(mymdl))$`Pr(>F)`
    

    不幸的是there is no designated way。但是您可以查看car:::print.Anova.mlm 的来源(通过在R 控制台中输入此内容)来了解它如何获得您想要的值:

    function (x, ...) 
    {
        if ((!is.null(x$singular)) && x$singular) 
            stop("singular error SSP matrix; multivariate tests unavailable\ntry summary(object, multivariate=FALSE)")
        test <- x$test
        repeated <- x$repeated
        ntests <- length(x$terms)
        tests <- matrix(NA, ntests, 4)
        if (!repeated) 
            SSPE.qr <- qr(x$SSPE)
        for (term in 1:ntests) {
            eigs <- Re(eigen(qr.coef(if (repeated) qr(x$SSPE[[term]]) else SSPE.qr, 
                x$SSP[[term]]), symmetric = FALSE)$values)
            tests[term, 1:4] <- switch(test, Pillai = Pillai(eigs, 
                x$df[term], x$error.df), Wilks = Wilks(eigs, x$df[term], 
                x$error.df), `Hotelling-Lawley` = HL(eigs, x$df[term], 
                x$error.df), Roy = Roy(eigs, x$df[term], x$error.df))
        }
        ok <- tests[, 2] >= 0 & tests[, 3] > 0 & tests[, 4] > 0
        ok <- !is.na(ok) & ok
        tests <- cbind(x$df, tests, pf(tests[ok, 2], tests[ok, 3], 
            tests[ok, 4], lower.tail = FALSE))
        rownames(tests) <- x$terms
        colnames(tests) <- c("Df", "test stat", "approx F", "num Df", 
            "den Df", "Pr(>F)")
        tests <- structure(as.data.frame(tests), heading = paste("\nType ", 
            x$type, if (repeated) 
                " Repeated Measures", " MANOVA Tests: ", test, " test statistic", 
            sep = ""), class = c("anova", "data.frame"))
        print(tests, ...)
        invisible(x)
    }
    <bytecode: 0x56032ea80990>
    <environment: namespace:car>
    

    在这种情况下,计算 p 值涉及到相当多的代码行。但是,我们可以轻松地创建 print 函数的修改版本来返回表 (tests),而不仅仅是打印它 (print(tests, ...)) 并返回原始对象 (invisible(x)):

    get_summary_for_print <- car:::print.Anova.mlm # copy the original print function (inclusive environment)
    body(get_summary_for_print) <- # replace the code of our copy
        local({ # to avoid pollution of environment by tmp
            tmp <- body(get_summary_for_print) # to avoid code duplication
            tmp[-(length(tmp)-(0:1))] # remove the last two code lines of the function
        })
    

    并像这样使用它:

    library(car)
    #> Loading required package: carData
    res <- Anova(lm(cbind(Sepal.Width, Sepal.Length, Petal.Width) ~ Species + Petal.Length, iris))
    res
    #> 
    #> Type II MANOVA Tests: Pillai test statistic
    #>              Df test stat approx F num Df den Df    Pr(>F)    
    #> Species       2   0.70215   26.149      6    290 < 2.2e-16 ***
    #> Petal.Length  1   0.63487   83.461      3    144 < 2.2e-16 ***
    #> ---
    #> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    str(get_summary_for_print(res))
    #> Classes 'anova' and 'data.frame':    2 obs. of  6 variables:
    #>  $ Df       : num  2 1
    #>  $ test stat: num  0.702 0.635
    #>  $ approx F : num  26.1 83.5
    #>  $ num Df   : num  6 3
    #>  $ den Df   : num  290 144
    #>  $ Pr(>F)   : num  7.96e-25 2.41e-31
    #>  - attr(*, "heading")= chr "\nType II MANOVA Tests: Pillai test statistic"
    

    【讨论】:

    • 在原始包中拆分 car:::print.Anova.mlm 会好得多,但是托管在 rforge car 上很难做出贡献。
    猜你喜欢
    • 2014-11-11
    • 2021-02-14
    • 2015-04-11
    • 2021-01-12
    • 2023-01-28
    • 1970-01-01
    • 2011-12-05
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多