How to get survdiff returned p value
Asked Answered
P

3

13

I am using R survival package, survdiff function. I wonder how to get the p value from the return value.

> diff = survdiff(Surv(Time, Censored) ~ Treatment+Gender, data = dat)
> diff
Call:
survdiff(formula = Surv(Time, Censored) ~ Treatment + Gender, 
    data = dat)

                            N Observed Expected (O-E)^2/E (O-E)^2/V
Treatment=Control, Gender=M 2        1     1.65  0.255876  0.360905
Treatment=Control, Gender=F 7        3     2.72  0.027970  0.046119
Treatment=IND, Gender=M     5        2     2.03  0.000365  0.000519
Treatment=IND, Gender=F     6        2     1.60  0.100494  0.139041

 Chisq= 0.5  on 3 degrees of freedom, p= 0.924 

I want to get the p value 0.924 using some function. Thanks.

Perdu answered 2/4, 2016 at 2:56 Comment(0)
C
10

The p value is not stored in the survdiff class, so it must be calculated on the fly at the time of output. To reproduce the p value one could use the chisq distribution function: "pchisq"

diff = survdiff(Surv(Time, Censored) ~ Treatment+Gender, data = dat)
pchisq(diff$chisq, length(diff$n)-1, lower.tail = FALSE)
Cathouse answered 2/4, 2016 at 4:38 Comment(5)
why lower.tail = FALSE?Postdate
@Omer An, See ?pchisq: lower.tail logical; if TRUE (default), probabilities are P[X ≤ x], otherwise, P[X > x]Cathouse
Yes, and why would you want to get P[X > x] ?Postdate
See also code of print.survdiff on Github. github.com/cran/survival/blob/…Newspaperman
After 5 years, I understand it's the same as: 1 - pchisq(diff$chisq, length(diff$n)-1, lower.tail = TRUE)Postdate
P
6

The code in the function print.survdiff that displays the p-value is:

cat("\n Chisq=", format(round(x$chisq, 1)), " on", df, 
            "degrees of freedom, p=", format(signif(1 - pchisq(x$chisq, 
                df), digits)), "\n")

The code leading up to it:

if (is.matrix(x$obs)) {
            otmp <- apply(x$obs, 1, sum)
            etmp <- apply(x$exp, 1, sum)
        }         else {
            otmp <- x$obs
            etmp <- x$exp
        }
        df <- (sum(1 * (etmp > 0))) - 1

And 'digits' is set to 3 in the argument list, so using the example on the surv.diff help page:

x <- survdiff(Surv(time, status) ~ pat.karno + strata(inst), data=lung) 
cat( "p=", format(signif(1 - pchisq(x$chisq, 
                 df), digits)) )
#p= 0.00326 

Addressing the comment: In the example the second code block reduces to:

 df <- with(x,    (sum(1 * (apply(x$exp, 1, sum) > 0))) - 1 )
> df
[1] 7
Pileate answered 2/4, 2016 at 5:59 Comment(2)
Thanks for the detailed explanation!Perdu
Am I supposed to set df = to something? I keep getting this error: Error in pchisq(survdiffRes$chisq, df) : Non-numeric argument to mathematical functionNonalignment
O
4

With the glance() function from the broom package, it is very easy to get the p.value.

diff = survdiff(Surv(Time, Censored) ~ Treatment+Gender, data = dat)

broom::glance(diff)$p.value
Oversupply answered 12/6, 2020 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.