Hazard ratios and p-values are computed taking into account time-to cardiovascular event and censoring. Each table (for males and females) are placed one beside the other and the resulting merged table is nice formatted.

1. Install compareGroups package from CRAN and then load it by typing:

install.packages("compareGroups")
library(compareGroups)

2. Load the PREDIMED example data available in compareGroups package:

data(predimed)

3. Compute time-to-event variable

by using Surv function from survival package.

predimed$tevent <- with(predimed, Surv(toevent, event == "Yes"))
label(predimed$tevent) <- "CV event"

4. Compute all descriptives and test from selected variables by using compareGroups function.

Note the use of formula argument as usual in R, so “.” indicates all variables in the dataset while “-” sign indicates removing. Put time-to-cardiovascular event computed at previous step on left side of “~” sign. Store the results in an object that can be used afterwards to perform plots or bivariate table itself. By the argument method we set wtn and p14 varible to be reported as median and quartiles instead of mean and standard deviation. Note the use of subset argument to select men or women, and the use of update method to repeat the instruction but now selecting women instead of men.

resMen <- compareGroups(tevent ~ . - toevent - event - sex, data = predimed, method = c(wtn = 2, p14 = 2), subset = sex == 'Male')
resWom <- update(resMen, subset = sex == 'Female')

5. Create the bivariate table by calling creaTable function

and passing the previous object computed by compareGroups function (res). Using this function you can customize how categorical variables are displayed (only percertage or absolute frequencies or both) by type argument or whether standard deviation appears inside brackets or separated by plus/minus symbol by sd.type argument. Also note the use of hide.no category which is useful to hide “no” level for those binary variables. If you only want to show “Female” category use hide argument for sex variable indicating which category is going to be hiden. This argument also applies to categorical variables with more than two categories. To show how many individuals have non-missing values in each described variable, set show.n argument to TRUE. In order to show p-value for each category and not the overall p-value set show.p.overall=FALSE. To specify the number of decimal digits to show use digitsarguments. In this example p14 have no decimals and for hormo only one digit. Finally, do not forget to type show.ratio=TRUE to display Hazard Ratio.

Note the use of update method applied to table already created for men to do the same for women.

restabMen <- createTable(resMen, digits = c(p14 = 0, hormo=1), type = 1, sd.type = 2, hide.no = "no", show.ratio = TRUE, show.p.overall = FALSE)
restabWom <- update(restabMen, x = resMen)

6. Combine the two tables (men and women) one beside of the other.

Use the cbind method as for matrices or data.frames objects in R to place the two tables side by side.

restab <- cbind("Males" = restabMen, "Females" = restabWom)

7. Export or print the bivariate table.

The bivariate table can be printed in the R console using the method print, i.e. just typing the name of the object:

restab

--------Summary descriptives table ---------

__________________________________________________________________________________________________________________________
                                                   Males                                        Females                   
                                ____________________________________________  ____________________________________________
                                No event    Event          HR        p.ratio  No event    Event          HR        p.ratio 
                                 N=2528     N=151                              N=2528     N=151                            
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Intervention group:                                                                                                        
    Control                       29.8%     38.4%         Ref.        Ref.      29.8%     38.4%         Ref.        Ref.   
    MedDiet + Nuts                36.7%     27.2%   0.54 [0.36;0.80]  0.002     36.7%     27.2%   0.54 [0.36;0.80]  0.002  
    MedDiet + VOO                 33.5%     34.4%   0.71 [0.49;1.03]  0.071     33.5%     34.4%   0.71 [0.49;1.03]  0.071  
Age                             66.0±6.49 68.3±7.02 1.06 [1.03;1.08] <0.001   66.0±6.49 68.3±7.02 1.06 [1.03;1.08] <0.001  
Smoking:                                                                                                                   
    Never                         27.0%     16.6%         Ref.        Ref.      27.0%     16.6%         Ref.        Ref.   
    Current                       24.8%     26.5%   1.63 [0.99;2.69]  0.056     24.8%     26.5%   1.63 [0.99;2.69]  0.056  
    Former                        48.2%     57.0%   1.92 [1.23;3.00]  0.004     48.2%     57.0%   1.92 [1.23;3.00]  0.004  
Body mass index                 29.3±3.31 29.4±3.72 1.01 [0.97;1.06]  0.565   29.3±3.31 29.4±3.72 1.01 [0.97;1.06]  0.565  
Waist circumference             103±9.57  104±10.1  1.01 [0.99;1.02]  0.391   103±9.57  104±10.1  1.01 [0.99;1.02]  0.391  
Waist-to-height ratio           0.62±0.06 0.62±0.06 13.2 [0.85;205]   0.065   0.62±0.06 0.62±0.06 13.2 [0.85;205]   0.065  
Hypertension                      77.7%     79.5%   1.20 [0.81;1.79]  0.358     77.7%     79.5%   1.20 [0.81;1.79]  0.358  
Type-2 diabetes                   52.0%     64.2%   1.59 [1.14;2.22]  0.006     52.0%     64.2%   1.59 [1.14;2.22]  0.006  
Dyslipidemia                      66.6%     58.9%   0.81 [0.58;1.11]  0.191     66.6%     58.9%   0.81 [0.58;1.11]  0.191  
Family history of premature CHD   17.4%     14.6%   0.89 [0.57;1.41]  0.627     17.4%     14.6%   0.89 [0.57;1.41]  0.627  
Hormone-replacement therapy      100.0%    100.0%         Ref.        Ref.     100.0%    100.0%         Ref.        Ref.   
MeDiet Adherence score          9 [8;10]  8 [7;10]  0.87 [0.81;0.94]  0.001   9 [8;10]  8 [7;10]  0.87 [0.81;0.94]  0.001  
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Or if you want to change some bivariate table header, such “p-value” instead of “p.ratio” use header.labels argument:

print(restab, header.labels = c(p.ratio = "p-value"))

--------Summary descriptives table ---------

__________________________________________________________________________________________________________________________
                                                   Males                                        Females                   
                                ____________________________________________  ____________________________________________
                                No event    Event          HR        p-value  No event    Event          HR        p-value 
                                 N=2528     N=151                              N=2528     N=151                            
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Intervention group:                                                                                                        
    Control                       29.8%     38.4%         Ref.        Ref.      29.8%     38.4%         Ref.        Ref.   
    MedDiet + Nuts                36.7%     27.2%   0.54 [0.36;0.80]  0.002     36.7%     27.2%   0.54 [0.36;0.80]  0.002  
    MedDiet + VOO                 33.5%     34.4%   0.71 [0.49;1.03]  0.071     33.5%     34.4%   0.71 [0.49;1.03]  0.071  
Age                             66.0±6.49 68.3±7.02 1.06 [1.03;1.08] <0.001   66.0±6.49 68.3±7.02 1.06 [1.03;1.08] <0.001  
Smoking:                                                                                                                   
    Never                         27.0%     16.6%         Ref.        Ref.      27.0%     16.6%         Ref.        Ref.   
    Current                       24.8%     26.5%   1.63 [0.99;2.69]  0.056     24.8%     26.5%   1.63 [0.99;2.69]  0.056  
    Former                        48.2%     57.0%   1.92 [1.23;3.00]  0.004     48.2%     57.0%   1.92 [1.23;3.00]  0.004  
Body mass index                 29.3±3.31 29.4±3.72 1.01 [0.97;1.06]  0.565   29.3±3.31 29.4±3.72 1.01 [0.97;1.06]  0.565  
Waist circumference             103±9.57  104±10.1  1.01 [0.99;1.02]  0.391   103±9.57  104±10.1  1.01 [0.99;1.02]  0.391  
Waist-to-height ratio           0.62±0.06 0.62±0.06 13.2 [0.85;205]   0.065   0.62±0.06 0.62±0.06 13.2 [0.85;205]   0.065  
Hypertension                      77.7%     79.5%   1.20 [0.81;1.79]  0.358     77.7%     79.5%   1.20 [0.81;1.79]  0.358  
Type-2 diabetes                   52.0%     64.2%   1.59 [1.14;2.22]  0.006     52.0%     64.2%   1.59 [1.14;2.22]  0.006  
Dyslipidemia                      66.6%     58.9%   0.81 [0.58;1.11]  0.191     66.6%     58.9%   0.81 [0.58;1.11]  0.191  
Family history of premature CHD   17.4%     14.6%   0.89 [0.57;1.41]  0.627     17.4%     14.6%   0.89 [0.57;1.41]  0.627  
Hormone-replacement therapy      100.0%    100.0%         Ref.        Ref.     100.0%    100.0%         Ref.        Ref.   
MeDiet Adherence score          9 [8;10]  8 [7;10]  0.87 [0.81;0.94]  0.001   9 [8;10]  8 [7;10]  0.87 [0.81;0.94]  0.001  
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Or if you want to create a PDF document with the table in a publish-ready format. Note the use of landscape=TRUE to place the table in horizontal direction. This may be useful for wide tables.

export2pdf(restab, file = "example4.pdf", header.labels = c(p.ratio = "p-value"), landscape = TRUE)

To create tables in PDF you must have some LaTeX compiler installed on your computer.