If the categories of the attributes in a contingency table are mere numbers, using only these numbers as column/row header is not enough -- a description what the numbers mean is called for. The picture below shows the cross-classification of household size vs. number of foreigners in a household sample:
Does anyone have experience in producing such tables using R+LaTeX?
I have a rather hackish solution of my own, but I'd like to see other approaches, too. Of course, it would be nice if a variant of this code was added to xtable
.
My solution consists of updating the rownames()
and colnames()
of the table. The row header goes into rownames()[1]
, and the column header goes into colnames()[1]
. Several things have to be remembered:
tabular
environment must be created by the user.&
The add.crosstab.headers
function takes care of everything. It can be applied to the result of an xtable()
call. Some helper functions are needed, too.
macrify <- function(m, s, bs='\\') {
paste(bs, m, '{', s, '}', sep='')
}
boldify <- function(s) {
macrify('textbf', s)
}
add.crosstab.headers <- function(t, row.header=NA, col.header=NA,
sanitize=boldify) {
rownames(t) <- sanitize(rownames(t))
colnames(t) <- sanitize(colnames(t))
if (!is.na(row.header)) {
colnames(t)[1] <- paste('&', colnames(t)[1])
rownames(t) <- paste('&', rownames(t))
row.header <- sanitize(row.header)
row.header <- macrify('rotatebox{90}', row.header)
multirow <- macrify('multirow', nrow(t))
multirow <- macrify(multirow, '*', bs='')
row.header <- macrify(multirow, row.header, bs='')
rownames(t)[1] <- paste(row.header, rownames(t)[1])
}
if (!is.na(col.header)) {
col.header <- sanitize(col.header)
multicolumn <- macrify('multicolumn', ncol(t))
multicolumn <- macrify(multicolumn, 'c', bs='')
col.header <- macrify(multicolumn, col.header, bs='')
col.header <- paste(col.header, '\\\\\n')
col.header <- paste(col.header, '&')
if (!is.na(row.header)) {
col.header <- paste('&', col.header)
}
colnames(t)[1] <- paste(col.header, colnames(t)[1])
}
t
}
The usage would be like this.
dat <- matrix(round(rnorm(9, 20, 10)), 3, 3)
t <- xtable(dat)
t <- add.crosstab.headers(t, row.header='Foreigners', col.header='Total persons')
print.xtable(t,
only.contents=TRUE,
booktabs=TRUE
, sanitize.text.function=identity
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With