You really should specify what you mean by confidence intervals, but assuming you want binomial confidence intervals for proportions, this is not necessarily pretty but it works. Take it as a starting point and adapt to your needs:
ci.table <- function(tbl, margin = NULL) {
binom_ci <- function(x, n) {
paste(round(binom.test(x, n)$conf.int, 3), collapse = " - ")
}
sweep_ci <- function(xx, nn) { mapply(FUN = binom_ci, xx, nn) }
if (length(margin))
result <- sweep(tbl, margin, margin.table(tt, margin),
"sweep_ci", check.margin = FALSE)
else
result <- sweep_ci(tbl, sum(tbl))
dim(result) <- dim(tbl)
as.table(result)
}
The binom_ci
function handles the formatting. I don't particularly like "x - y" for confidence intervals, but I have found that most people understand this better than for example "(x, y)"...
MWE:
ddff <- data.frame(
A = sample(c("A", "B", "C"), 20, replace = TRUE),
B = sample(c("C", "D"), 20, replace = TRUE)
)
tt <- table(ddff$A, ddff$B)
ci.table(tt)
ci.table(tt, 1)
ci.table(tt, 2)