Survival times, in months, from diagnosis until death for 48 patients with multiple myeloma, together with seven prognostic variables (Collett, 2023, Example 1.3).
Format
A data frame with 48 rows and 10 variables:
- patient
Patient number (1-48).
- time
Survival time in months from diagnosis.
- status
Event indicator: 1 = death from multiple myeloma, 0 = right-censored.
- age
Age at diagnosis in years (50-80).
- sex
Sex: 1 = male, 2 = female.
- bun
Blood urea nitrogen level.
- ca
Serum calcium level.
- hb
Haemoglobin level.
- pcells
Percentage of plasma cells in the bone marrow.
- protein
Bence-Jones protein in the urine: 0 = absent, 1 = present.
Source
Collett, D. (2023) Modelling Survival Data in Medical Research, 4th ed. Chapman & Hall/CRC, Example 1.3 (Table 1.3). Original data from Krall, Uthoff and Harley (1975); the study was carried out at the Medical Center of the University of West Virginia, USA.
Details
There are 36 deaths among the 48 patients. The time origin is the date of diagnosis and the endpoint is death from multiple myeloma; patients alive at the end of the study contribute censored times.
The data are used throughout the book: life-table estimation (Examples 2.2 and 2.6), Cox regression with several covariates, variable selection and interaction (Examples 3.2-3.20), model checking and influence diagnostics (Examples 4.5, 4.8 and 4.9) and a Weibull model for a prognostic index (Example 5.16).
Aliases
The data set is available under the aliases d1.3, d2.2, d2.6, d3.2,
d3.5, d3.7, d3.8, d3.9, d3.15, d3.17, d3.19, d3.20, d4.5,
d4.8, d4.9, d5.16; dX.Y is the alias for the data set used in
Example X.Y of Collett (2023). See dataset_by_exercise for the complete
index.
Examples
# Collett (2023), Chapter 17 style -----------------------------------
# Examples 2.2 and 2.6: the survivor function for a single sample
survival::survfit(survival::Surv(time, status) ~ 1, data = myeloma)
#> Call: survfit(formula = survival::Surv(time, status) ~ 1, data = myeloma)
#>
#> n events median 0.95LCL 0.95UCL
#> [1,] 48 36 17 13 40
# Examples 3.2, 3.5, 3.8, 3.9, 3.15, 3.17, 3.19 and 3.20: Cox model
fit_myeloma <- survival::coxph(
survival::Surv(time, status) ~ age + sex + bun + ca + hb + pcells + protein,
data = myeloma
)
summary(fit_myeloma)
#> Call:
#> survival::coxph(formula = survival::Surv(time, status) ~ age +
#> sex + bun + ca + hb + pcells + protein, data = myeloma)
#>
#> n= 48, number of events= 36
#>
#> coef exp(coef) se(coef) z Pr(>|z|)
#> age -0.018056 0.982106 0.027833 -0.649 0.516521
#> sex -0.249473 0.779211 0.403093 -0.619 0.535985
#> bun 0.022661 1.022919 0.006110 3.709 0.000208 ***
#> ca 0.013265 1.013353 0.132681 0.100 0.920363
#> hb -0.133017 0.875450 0.068527 -1.941 0.052249 .
#> pcells -0.001359 0.998642 0.006588 -0.206 0.836585
#> protein -0.683269 0.504964 0.429395 -1.591 0.111556
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> exp(coef) exp(-coef) lower .95 upper .95
#> age 0.9821 1.0182 0.9300 1.037
#> sex 0.7792 1.2833 0.3536 1.717
#> bun 1.0229 0.9776 1.0107 1.035
#> ca 1.0134 0.9868 0.7813 1.314
#> hb 0.8755 1.1423 0.7654 1.001
#> pcells 0.9986 1.0014 0.9858 1.012
#> protein 0.5050 1.9803 0.2177 1.172
#>
#> Concordance= 0.705 (se = 0.048 )
#> Likelihood ratio test= 17.53 on 7 df, p=0.01
#> Wald test = 20.01 on 7 df, p=0.006
#> Score (logrank) test = 25.59 on 7 df, p=6e-04
#>
# Example 3.7: lasso variable selection (the book uses the penalized package)
# The fitting routine prints its progress; it is captured here so that the
# selected coefficients are easy to read.
progress <- utils::capture.output(
lass <- penalized::penalized(
survival::Surv(myeloma$time, myeloma$status),
penalized = ~ age + sex + bun + ca + hb + pcells + protein,
lambda1 = 30,
data = myeloma
)
)
round(lass@penalized, 3)
#> age sex bun ca hb pcells protein
#> 0.000 0.000 0.018 0.000 -0.014 0.002 0.000
# Examples 4.5, 4.8 and 4.9: residuals and the proportional hazards assumption
head(stats::residuals(fit_myeloma, type = "martingale"))
#> 1 2 3 4 5 6
#> 0.8463455 -1.1085112 0.9199577 0.4673966 0.7818134 -0.1657903
survival::cox.zph(fit_myeloma)
#> chisq df p
#> age 0.1280 1 0.72
#> sex 0.7724 1 0.38
#> bun 0.8564 1 0.35
#> ca 0.3629 1 0.55
#> hb 0.0428 1 0.84
#> pcells 2.1903 1 0.14
#> protein 0.4325 1 0.51
#> GLOBAL 4.0974 7 0.77
# Example 5.16: Weibull model with a prognostic index
survival::survreg(
survival::Surv(time, status) ~ age + bun + hb,
data = myeloma, dist = "weibull"
)
#> Call:
#> survival::survreg(formula = survival::Surv(time, status) ~ age +
#> bun + hb, data = myeloma, dist = "weibull")
#>
#> Coefficients:
#> (Intercept) age bun hb
#> 1.89583079 0.01154694 -0.01553197 0.12174295
#>
#> Scale= 0.900254
#>
#> Loglik(model)= -153.4 Loglik(intercept only)= -159.8
#> Chisq= 12.82 on 3 degrees of freedom, p= 0.00505
#> n= 48
# Modern tools --------------------------------------------------------
if (requireNamespace("broom", quietly = TRUE)) {
broom::tidy(fit_myeloma, exponentiate = TRUE, conf.int = TRUE)
}
#> # A tibble: 7 × 7
#> term estimate std.error statistic p.value conf.low conf.high
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 age 0.982 0.0278 -0.649 0.517 0.930 1.04
#> 2 sex 0.779 0.403 -0.619 0.536 0.354 1.72
#> 3 bun 1.02 0.00611 3.71 0.000208 1.01 1.04
#> 4 ca 1.01 0.133 0.1000 0.920 0.781 1.31
#> 5 hb 0.875 0.0685 -1.94 0.0522 0.765 1.00
#> 6 pcells 0.999 0.00659 -0.206 0.837 0.986 1.01
#> 7 protein 0.505 0.429 -1.59 0.112 0.218 1.17
if (requireNamespace("glmnet", quietly = TRUE)) {
x <- as.matrix(myeloma[c("age", "sex", "bun", "ca", "hb", "pcells", "protein")])
cv <- glmnet::cv.glmnet(x, survival::Surv(myeloma$time, myeloma$status), family = "cox")
stats::coef(cv, s = "lambda.min")
}
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> Warning: Starting in glmnet 5.1, the default Cox tie-handling method will change from 'breslow' to 'efron' (matching survival::coxph). To silence this message and lock in the v5.0 default, pass cox.ties = 'breslow' explicitly. To preview the v5.1 behavior, pass cox.ties = 'efron'.
#> 7 x 1 sparse Matrix of class "dgCMatrix"
#> 1
#> age .
#> sex .
#> bun 0.01409621
#> ca .
#> hb -0.07588249
#> pcells .
#> protein -0.30465604
if (requireNamespace("rms", quietly = TRUE)) {
rms::cph(
survival::Surv(time, status) ~ age + sex + bun + ca + hb + pcells + protein,
data = myeloma, x = TRUE, y = TRUE
)
}
#> Cox Proportional Hazards Model
#>
#> rms::cph(formula = survival::Surv(time, status) ~ age + sex +
#> bun + ca + hb + pcells + protein, data = myeloma, x = TRUE,
#> y = TRUE)
#>
#> Model Tests Discrimination
#> Indexes
#> Obs 48 LR chi2 17.53 R2 0.309
#> Events 36 d.f. 7 R2(7,48) 0.197
#> Center -2.219 P(> chi2) 0.0143 R2(7,36) 0.254
#> Score chi2 25.59 Dxy 0.410
#> P(> chi2) 0.0006
#>
#> Coef S.E. Wald Z P(>|Z|)
#> age -0.0181 0.0278 -0.65 0.5165
#> sex -0.2495 0.4031 -0.62 0.5360
#> bun 0.0227 0.0061 3.71 0.0002
#> ca 0.0133 0.1327 0.10 0.9204
#> hb -0.1330 0.0685 -1.94 0.0523
#> pcells -0.0014 0.0066 -0.21 0.8366
#> protein -0.6833 0.4294 -1.59 0.1116
#>