therneau/survival

`plot(cox.zph(...), panel.first = ...)` does not work

Closed this issue · 2 comments

plot(cox.zph(...), panel.first = ...) does not work. It is only cosmetics, but it would nice to have to draw reference lines below the curve and residuals.

# example from ?cox.zph
library(survival)
fit <- coxph(Surv(futime, fustat) ~ age + ecog.ps, data = ovarian)
temp <- cox.zph(fit) 
plot(temp, panel.first = abline(h = 0))
# Error in int_abline(a = a, b = b, h = h, v = v, untf = untf, ...) : 
#   plot.new has not been called yet

Not sure if it is the issue here, but according to panel.first description in ?plot.default:

Note that this works by lazy evaluation: passing this argument from other plot methods may well not work since it may be evaluated too early.

This was a puzzler. I have never used panel. first nor was I aware of it.

The plot.cox.zph routine needs to check if 'xaxt' is in the ... args before calling plot(), and had the code of plotargs <- list(...); thn check for xaxt in plotargs. It turns out that this forces an early evaluation of your panel.first argument, which messes everything up. But -- version 3.5 (?) of R added the ...length() and ...names() functions, which get that information without evaluation of the ... component. The first was useful in [.survfit, which is how I know of it.

Now fixed in my development copy, and will migrate to github in due course once I've run all the tests.

Edit: The fix works as expected. In the reprex below, the line is drawn on the first plot but I have been fooled because RStudio showed the last plot... Sorry for the trouble!

It is documented in ?survival:::plot.cox.zph() (description of the var argument):

the set of variables for which plots are desired. By default, plots are produced in turn for each variable of a model. Selection of a single variable allows other features to be added to the plot, e.g., a horizontal line at zero or a main title.

This has been superseded by a subscripting method; see the example below.


Thank you for looking at it.

I have no longer an error if I use panel.first, but it draws nothing. @therneau: Maybe the issue should be reopened?

remotes::install_github("therneau/survival")
library(survival)

fit <- coxph(Surv(futime, fustat) ~ age + ecog.ps, ovarian)
temp <- cox.zph(fit)

plot(temp, panel.first = abline(h = 0, col = 2, lwd = 5)) # no line drawn
abline(h = 0, col = 2, lwd = 5) # line drawn over the curve

sessionInfo()
# R version 4.3.3 (2024-02-29)
# Platform: x86_64-redhat-linux-gnu (64-bit)
# Running under: Fedora Linux 39 (Workstation Edition)
# 
# Matrix products: default
# BLAS/LAPACK: FlexiBLAS OPENBLAS-OPENMP;  LAPACK version 3.11.0
# 
# locale:
#  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C               LC_TIME=fr_FR.UTF-8       
#  [4] LC_COLLATE=fr_FR.UTF-8     LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
#  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
# [10] LC_TELEPHONE=C             LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
# 
# time zone: Europe/Paris
# tzcode source: system (glibc)
# 
# attached base packages:
# [1] stats     graphics  grDevices utils     datasets  methods   base     
# 
# other attached packages:
# [1] survival_3.7-2
# 
# loaded via a namespace (and not attached):
#  [1] processx_3.8.4 compiler_4.3.3 Matrix_1.6-5   R6_2.5.1       cli_3.6.2     
#  [6] tools_4.3.3    remotes_2.5.0  splines_4.3.3  grid_4.3.3     desc_1.4.3    
# [11] callr_3.7.6    ps_1.7.6       pkgbuild_1.4.4 lattice_0.22-5