After installation (usinginstall.packages("rifttable"orremotes::install_github("stopsack/rifttable")), load thepackage with:
Thecancer dataset from survival package is usedhere:
data(cancer,package ="survival")cancer<- cancer|> tibble::as_tibble()|> dplyr::mutate(# The exposure (here, 'sex') must be categoricalsex =factor( sex,levels =1:2,labels =c("Male","Female") ),time = time/365.25,status = status-1 )cancer#> # A tibble: 228 × 10#> inst time status age sex ph.ecog ph.karno pat.karno meal.cal wt.loss#> <dbl> <dbl> <dbl> <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>#> 1 3 0.838 1 74 Male 1 90 100 1175 NA#> 2 3 1.25 1 68 Male 0 90 90 1225 15#> 3 3 2.77 0 56 Male 0 90 90 NA 15#> 4 5 0.575 1 57 Male 1 90 60 1150 11#> 5 1 2.42 1 60 Male 0 100 90 NA 0#> 6 12 2.80 0 74 Male 1 50 80 513 0#> 7 7 0.849 1 68 Female 2 70 60 384 10#> 8 11 0.988 1 71 Female 2 60 80 538 1#> 9 1 0.597 1 53 Male 1 70 80 825 16#> 10 7 0.454 1 61 Male 2 70 70 271 34#> # ℹ 218 more rowsSet the table design:
design1<- tibble::tibble(label =c("Outcomes","Total","Outcomes/Total","Risk","Risk (CI)","Outcomes (Risk)","Outcomes/Total (Risk)","RR","RD" ))|> dplyr::mutate(type = label,exposure ="sex",outcome ="status" )Generate rifttable:
rifttable(design = design1,data = cancer)#> # A tibble: 9 × 3#> sex Male Female#> <chr> <chr> <chr>#> 1 Outcomes 112 53#> 2 Total 138 90#> 3 Outcomes/Total 112/138 53/90#> 4 Risk 0.81 0.59#> 5 Risk (CI) 0.81 (0.74, 0.87) 0.59 (0.49, 0.68)#> 6 Outcomes (Risk) 112 (0.81) 53 (0.59)#> 7 Outcomes/Total (Risk) 112/138 (0.81) 53/90 (0.59)#> 8 RR 1 (reference) 0.73 (0.60, 0.88)#> 9 RD 0 (reference) -0.22 (-0.34, -0.10)This example uses thedesign of Example 1 above. So far,the tables produced when just running the code shown had an appearancelike output in the R console. To obtain formatted tables in HTML andother output documents, pipe the output ofrifttable() to atable formatting function such as
knitr::kable(): works well with all output formats, butsupports only limited formatting. Add to the YAML header a statementdf_print: kable to print all tables using kable.gt::gt(): supports more advanced formatting but outputis no longer human-readable.The rifttable package provides thert_gt() wrapperfunction. When knitting to HTML, PDF, or Word, it functions as a wrapperforgt::gt(), passing along indentations from thelabel of the tabledesign. When knitting to aMarkdown document (.md), such asgithub_document (in RMarkdown) orgfm (inQuarto),rt_gt() will automatically provide plain tableoutput using the kable package.
| sex | Male | Female |
|---|---|---|
| Outcomes | 112 | 53 |
| Total | 138 | 90 |
| Outcomes/Total | 112/138 | 53/90 |
| Risk | 0.81 | 0.59 |
| Risk (CI) | 0.81 (0.74, 0.87) | 0.59 (0.49, 0.68) |
| Outcomes (Risk) | 112 (0.81) | 53 (0.59) |
| Outcomes/Total (Risk) | 112/138 (0.81) | 53/90 (0.59) |
| RR | 1 (reference) | 0.73 (0.60, 0.88) |
| RD | 0 (reference) | -0.22 (-0.34, -0.10) |
To use thedesign as columns instead of rows, showingonly threetypes:
rifttable(design = design1|> dplyr::filter(label%in%c("Outcomes/Total (Risk)","RR","RD" )),data = cancer,layout ="cols")|>rt_gt()| sex | Outcomes/Total (Risk) | RR | RD |
|---|---|---|---|
| Male | 112/138 (0.81) | 1 (reference) | 0 (reference) |
| Female | 53/90 (0.59) | 0.73 (0.60, 0.88) | -0.22 (-0.34, -0.10) |
Survival outcomes use thetime andeventvariables in thedesign (andtype2, with lateentry, as insurvival::Surv()), rather than theoutcome variable used for binary, categorical, orcontinuous outcomes.
Set table design:
design2<- tibble::tribble(# Elements that vary by row:~label,~stratum,~confounders,~type,"**Overall**",NULL,"","blank"," Events",NULL,"","events"," Person-years",NULL,"","time"," Rate/1000 py (95% CI)",NULL,"","rate (ci)"," Unadjusted HR (95% CI)",NULL,"","hr"," Age-adjusted HR (95% CI)",NULL,"+ age","hr","",NULL,"","blank","**Stratified models**",NULL,"","","*ECOG PS1* (events/N)",1,"","events/total"," Unadjusted",1,"","hr"," Age-adjusted",1,"+ age","hr","*ECOG PS2* (events/N)",2,"","events/total"," Unadjusted",2,"","hr"," Age-adjusted",2,"+ age","hr","",NULL,"","","**Joint model**, age-adj.",NULL,"",""," ECOG PS1",1,"+ age","hr_joint"," ECOG PS2",2,"+ age","hr_joint")|># Elements that are the same for all rows: dplyr::mutate(exposure ="sex",event ="status",time ="time",effect_modifier ="ph.ecog" )Generate rifttable:
| sex | Male | Female |
|---|---|---|
| Overall | ||
| Events | 82 | 44 |
| Person-years | 70 | 59 |
| Rate/1000 py (95% CI) | 1164.8 (938.1, 1446.3) | 746.7 (555.7, 1003.4) |
| Unadjusted HR (95% CI) | 1 (reference) | 0.60 (0.41, 0.86) |
| Age-adjusted HR (95% CI) | 1 (reference) | 0.60 (0.41, 0.86) |
| Stratified models | ||
| ECOG PS1 (events/N) | 54/71 | 28/42 |
| Unadjusted | 1 (reference) | 0.53 (0.33, 0.85) |
| Age-adjusted | 1 (reference) | 0.53 (0.33, 0.85) |
| ECOG PS2 (events/N) | 28/29 | 16/21 |
| Unadjusted | 1 (reference) | 0.70 (0.37, 1.30) |
| Age-adjusted | 1 (reference) | 0.68 (0.34, 1.36) |
| Joint model, age-adj. | ||
| ECOG PS1 | 1 (reference) | 0.55 (0.35, 0.88) |
| ECOG PS2 | 1.54 (0.98, 2.44) | 1.10 (0.62, 1.98) |
type andtype2design3<- tibble::tribble(~label,~stratum,~type,~type2,"ECOG PS1",1,"events/total","hr","ECOG PS2",2,"events/total","hr")|> dplyr::mutate(exposure ="sex",event ="status",time ="time",confounders ="+ age",effect_modifier ="ph.ecog" )rifttable(design = design3,data = cancer|> dplyr::filter(ph.ecog%in%1:2))|>rt_gt()| sex | Male | Female |
|---|---|---|
| ECOG PS1 | 54/71 | 28/42 |
| 1 (reference) | 0.53 (0.33, 0.85) | |
| ECOG PS2 | 28/29 | 16/21 |
| 1 (reference) | 0.68 (0.34, 1.36) |
With estimatetype as columns:
rifttable(design = design3,data = cancer|> dplyr::filter(ph.ecog%in%1:2),layout ="cols",type2_layout ="cols")|>rt_gt()| sex | ECOG PS1 | ECOG PS1 | ECOG PS2 | ECOG PS2 |
|---|---|---|---|---|
| Male | 54/71 | 1 (reference) | 28/29 | 1 (reference) |
| Female | 28/42 | 0.53 (0.33, 0.85) | 16/21 | 0.68 (0.34, 1.36) |
Request rounding to 1 decimal digit in some cases; add a continuoustrend,i.e., the slope per one unit of thetrendvariable:
tibble::tribble(~label,~stratum,~type,~digits,"Marginal mean (95% CI)",NULL,"mean (ci)",1," Male","Male","mean",NA," Female","Female","mean",NA,"",NULL,"",NA,"Stratified model",NULL,"",NA," Male","Male","diff",1," Female","Female","diff",1,"",NULL,"",NA,"Joint model",NULL,"",NA," Male","Male","diff_joint",NA," Female","Female","diff_joint",NA)|> dplyr::mutate(exposure ="ph.ecog_factor",trend ="ph.ecog",outcome ="age",effect_modifier ="sex" )|>rifttable(data = cancer|> dplyr::filter(ph.ecog<3)|> dplyr::mutate(ph.ecog_factor =factor(ph.ecog)) )|>rt_gt()| ph.ecog_factor | 0 | 1 | 2 | Trend |
|---|---|---|---|---|
| Marginal mean (95% CI) | 61.2 (58.8, 63.5) | 61.5 (59.8, 63.1) | 66.2 (64.0, 68.5) | |
| Male | 63.00 | 62.79 | 65.00 | |
| Female | 58.70 | 59.19 | 67.90 | |
| Stratified model | ||||
| Male | 0 (reference) | -0.2 (-3.9, 3.5) | 2.0 (-2.5, 6.5) | 0.9 (-1.3, 3.2) |
| Female | 0 (reference) | 0.5 (-3.5, 4.5) | 9.2 (4.5, 13.9) | 4.4 (2.0, 6.7) |
| Joint model | ||||
| Male | 0 (reference) | -0.21 (-3.75, 3.33) | 2.00 (-2.32, 6.32) | 0.93 (-1.33, 3.19) |
| Female | -4.30 (-8.70, 0.11) | -3.81 (-7.74, 0.12) | 4.90 (0.15, 9.66) | 4.36 (1.97, 6.75) |