Crosstable is an extension for the class table that have useful methods to print the table with percents and chisquare expected values. You can use as any regular table call functions like apply
, margin.table
and chisq.test
.
This function is designed to be used in a way that you can see the results in the console.
library(multitabulation)
#> Loading required package: magrittr
#> Loading required package: stringr
library(magrittr)
# Generate Random data
<- sample(c(1,2), 131, replace=TRUE) %>%
gender factor(levels=c(1,2), labels=c("Man", "Woman"))
<- sample(c(1,2,3), 131, replace=TRUE) %>%
strata factor(levels=c(1,2,3), labels=c("Low", "Middle", "High"))
<- sample(c(1,2), 131, replace=TRUE) %>%
party factor(levels=c(1,2), labels=c("Right", "Left"))
crosstable(strata, party, gender, stats=c("count", "row", "column", "total"))
#> |----------------------------------------------------------------------------------------|
#> | | | gender |
#> | | |---------------------------------------------------------------------------|
#> | | | Man | Woman |
#> | | |---------------------------------------------------------------------------|
#> | | | statistic | statistic |
#> | | |---------------------------------------------------------------------------|
#> |strata|party|count|% of row|% of column|% of total|count|% of row|% of column|% of total|
#> |------|-----|-----|--------|-----------|----------|-----|--------|-----------|----------|
#> |Low |Right| 7| 11.67%| 36.84%| 5.34%| 12| 16.90%| 63.16%| 9.16%|
#> | |Left | 7| 11.67%| 53.85%| 5.34%| 6| 8.45%| 46.15%| 4.58%|
#> |Middle|Right| 15| 25.00%| 51.72%| 11.45%| 14| 19.72%| 48.28%| 10.69%|
#> | |Left | 11| 18.33%| 39.29%| 8.40%| 17| 23.94%| 60.71%| 12.98%|
#> |High |Right| 8| 13.33%| 47.06%| 6.11%| 9| 12.68%| 52.94%| 6.87%|
#> | |Left | 12| 20.00%| 48.00%| 9.16%| 13| 18.31%| 52.00%| 9.92%|
#> |----------------------------------------------------------------------------------------|
You can use as_flextable
to make a table ready to be printed in a report. You can combine flextable with officer in order to export the table to Ms Office.
library(multitabulation)
library(flextable)
library(magrittr)
crosstable(strata, party, gender, stats=c("count", "column")) %>%
as_flextable
strata | party | gender | |||
Man | Woman | ||||
statistic | statistic | ||||
count | % of column | count | % of column | ||
Low | Right | 7 | 36.84% | 12 | 63.16% |
Left | 7 | 53.85% | 6 | 46.15% | |
Middle | Right | 15 | 51.72% | 14 | 48.28% |
Left | 11 | 39.29% | 17 | 60.71% | |
High | Right | 8 | 47.06% | 9 | 52.94% |
Left | 12 | 48.00% | 13 | 52.00% |
Crosstable is basically an extension of table class, so you can use in almost the same way than a regular table, so you can perform the chisq.test
<- with(MASS::bacteria, crosstable(y, trt, stats=c("count", "column")))
tab <- chisq.test(tab)
tabxsq
tabxsq#>
#> Pearson's Chi-squared test
#>
#> data: tab
#> X-squared = 6.6585, df = 2, p-value = 0.03582
Also, you can include the expected values of chisq.test
in the table report using add.tables
.
add.tables(tab, format="(0.00)", "(expected)" = tabxsq$expected) %>%
as_flextable
y | trt | ||||||||
placebo | drug | drug+ | |||||||
statistic | statistic | statistic | |||||||
count | % of column | (expected) | count | % of column | (expected) | count | % of column | (expected) | |
n | 12 | 27.91% | (18.76) | 18 | 41.86% | (12.12) | 13 | 30.23% | (12.12) |
y | 84 | 47.46% | (77.24) | 44 | 24.86% | (49.88) | 49 | 27.68% | (49.88) |
If you prefer the stats on rows, you can use stats.on.cols=FALSE
crosstable(strata, party, gender, stats=c("count", "column"), stats.on.cols=FALSE) %>%
as_flextable
strata | party | statistic | gender | |
Man | Woman | |||
Low | Right | count | 7.00 | 12.00 |
% of column | 36.84% | 63.16% | ||
Left | count | 7.00 | 6.00 | |
% of column | 53.85% | 46.15% | ||
Middle | Right | count | 15.00 | 14.00 |
% of column | 51.72% | 48.28% | ||
Left | count | 11.00 | 17.00 | |
% of column | 39.29% | 60.71% | ||
High | Right | count | 8.00 | 9.00 |
% of column | 47.06% | 52.94% | ||
Left | count | 12.00 | 13.00 | |
% of column | 48.00% | 52.00% |
You can use an existing table and turn it into a crosstable
. You can use col.vars
or row.vars
crosstable(Titanic, col.vars=c("Sex", "Survived"), stats=c("count", "column")) %>%
as_flextable
Class | Age | Sex | |||||||
Male | Female | ||||||||
Survived | Survived | ||||||||
No | Yes | No | Yes | ||||||
statistic | statistic | statistic | statistic | ||||||
count | % of column | count | % of column | count | % of column | count | % of column | ||
1st | Child | 0 | 0.00% | 5 | 83.33% | 0 | 0.00% | 1 | 16.67% |
Adult | 118 | 36.99% | 57 | 17.87% | 4 | 1.25% | 140 | 43.89% | |
2nd | Child | 0 | 0.00% | 11 | 45.83% | 0 | 0.00% | 13 | 54.17% |
Adult | 154 | 59.00% | 14 | 5.36% | 13 | 4.98% | 80 | 30.65% | |
3rd | Child | 35 | 44.30% | 13 | 16.46% | 17 | 21.52% | 14 | 17.72% |
Adult | 387 | 61.72% | 75 | 11.96% | 89 | 14.19% | 76 | 12.12% | |
Crew | Child | 0 | NaN% | 0 | NaN% | 0 | NaN% | 0 | NaN% |
Adult | 670 | 75.71% | 192 | 21.69% | 3 | 0.34% | 20 | 2.26% |
You can use dnn
to set the names of the variables.
with(MASS::bacteria, crosstable(y, trt, stats=c("count", "column"), dnn=c("Result", "Treatment"))) %>%
as_flextable
Result | Treatment | |||||
placebo | drug | drug+ | ||||
statistic | statistic | statistic | ||||
count | % of column | count | % of column | count | % of column | |
n | 12 | 27.91% | 18 | 41.86% | 13 | 30.23% |
y | 84 | 47.46% | 44 | 24.86% | 49 | 27.68% |
If you use a wheighted survey or data base, you can use the formula mode.
crosstable(Freq ~ Type + Cont, stats=c("count", "row"), data=MASS::housing) %>%
as_flextable
Type | Cont | |||
Low | High | |||
statistic | statistic | |||
count | % of row | count | % of row | |
Tower | 219 | 30.72% | 181 | 18.70% |
Apartment | 317 | 44.46% | 448 | 46.28% |
Atrium | 82 | 11.50% | 157 | 16.22% |
Terrace | 95 | 13.32% | 182 | 18.80% |