目的
ftable 関数が返す多重クロス集計のオブジェクトにより,多重クロス集計表をパーセント付きで LaTeX ソースとして出力する。
使用法
xtable.ftable(obj, caption="caption", label="label", percentage=c("row", "col", "none"), same.line=TRUE,
percentage.font=c("small", "footnotesize", "tiny", "normalsize"),
position=c("c", "r", "l"), rev=-1.5, booktabs=FALSE)
引数
obj ftable などが返す ftable オブジェクト
caption="caption" キャプション
label="label" ラベル
percentage=c("row", "col", "none") % を付ける方向
same.line=TRUE % を度数と同じ行に付けるときは TRUE にする
percentage.font=c("small", "footnotesize", "tiny", "normalsize")
LaTeX でのフォントサイズの指定 tiny, footnotesize など
position=c("c", "r", "l") フィールド内での配置 "c", "r", "l" のいずれか
rev=-1.5 行間を詰めるための,逆改行の大きさをミリ単位で指定(逆改行しない場合には 0 を指定する)
booktabs=FALSE TRUE なら \hline の代わりに \toprule, \midrule, \bottomrule を使う
ソース
インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/xtable-ftable.R", encoding="euc-jp")
xtable.ftable <- function( obj, # crosstabsn が返す ftable オブジェクト
caption="caption", # キャプション
label="label", # ラベル
percentage=c("row", "col", "none"), # % を付ける方向
same.line=TRUE, # % を度数と同じ行に付けるときは TRUE にする
percentage.font=c("small", "footnotesize", "tiny", "normalsize"), # LaTeX でのフォントサイズの指定 tiny, footnotesize など
position=c("c", "r", "l"), # フィールド内での配置 "c", "r", "l" のいずれか
rev=-1.5, # 行間を詰めるための,逆改行の大きさをミリ単位で指定(逆改行しない場合には 0 を指定する)
booktabs=FALSE) # TRUE なら \hline の代わりに \toprule, \midrule, \bottomrule を使う
# ftable 関数が返した ftable クラスのオブジェクトを入力し,LaTeX ソースを出力する
# formula で指定する。~ の左辺には1個のみ指定できる
# Sweave から使用するのが便利
# 使用例
# Titanic
# x <- ftable(Survived ~ ., data = Titanic)
# a <- ftable(Survived ~ Sex + Class + Age, data = x)
# xtable(a)
# xtable(ftable(Survived ~ Sex + Class, data = x))
{ row.vars <- attr(obj, "row.vars")
n.row.vars <- length(row.vars)
names.row.vars <- names(row.vars)
m.row.vars <- sapply(row.vars, length)
col.vars <- attr(obj, "col.vars")
n.col.vars <- length(col.vars)
names.col.vars <- names(col.vars)
m.col.vars <- sapply(col.vars, length)
if (n.col.vars != 1) {
stop("col.vars が 1 変数の ftable オブジェクトしか扱えません")
}
nrow <- nrow(obj)
side <- matrix("", nrow, n.row.vars)
n.block <- nrow/m.row.vars[n.row.vars]
side[, n.row.vars] <- unlist(rep(row.vars[n.row.vars], n.block))
for (i in seq_len(n.row.vars-1)) {
every <- prod(m.row.vars[(i+1):n.row.vars])
side[(0:(nrow-1))%%every==0, i] <- unlist(row.vars[i])
}
percentage <- match.arg(percentage)
if (percentage == "none") {
same.line <- FALSE
}
percentage.font <- match.arg(percentage.font)
position <- match.arg(position)
if (booktabs) {
toprule <- "\\toprule"
midrule <- "\\midrule"
}
else {
toprule <- midrule <- "\\hline"
}
col.vars <- c(unlist(col.vars[[1]]), "合計")
fac <- same.line+1
if (same.line) {
pos <- c(rep(position, n.row.vars), rep(paste(position, "@{}", position), m.col.vars+1))
header <- paste(paste(names.row.vars, collapse=" & "), paste("&", paste(col.vars, "\\%", sep=" & ", collapse=" & ")))
fmt <- sprintf("%%d & {\\%s \\textit{%%6.1f}}", percentage.font)
}
else {
pos <- rep(position, m.col.vars+1+n.row.vars)
header <- paste(paste(names.row.vars, collapse=" & "), paste(col.vars, collapse=" & "), sep=" & ")
fmt <- sprintf("{\\%s \\textit{%%5.1f}}", percentage.font)
}
cat("\\begin{table}[htbp]\n",
"\\caption{", caption, "}\n",
"\\label{", label, "}\n",
"\\centering\n",
"\\begin{tabular}{", pos, "} ", toprule, " \n", sep="")
cat(paste(rep("&", n.row.vars), collapse=" "))
cat(sprintf(" \\multicolumn{%i}{c}{%s}\\\\ \\cline{%i-%i}\n",
fac*m.col.vars[1], names.col.vars[1], n.row.vars+1, fac*m.col.vars[1]+n.row.vars))
cat(header, " \\\\ ", midrule, "\n", sep="")
for (k in 1:n.block) {
end <- k*m.row.vars[n.row.vars]
begin <- end-m.row.vars[n.row.vars]+1
block <- addmargins(obj[begin:end, ])
side.block <- rbind(side[begin:end, , drop=FALSE ], c(rep("", n.row.vars-1), "合計"))
if (percentage == "row") {
pct <- block/block[, m.col.vars+1]*100
}
else {
pct <- t(t(block)/block[m.row.vars[n.row.vars]+1,]*100)
}
n <- m.row.vars[n.row.vars]+1
for (i in 1:n) {
cat(sprintf("%s &", side.block[i,]))
if (same.line) {
cat(gsub("NaN", "---", paste(apply(cbind(block[i,], pct[i,]), 1, function(y) sprintf(fmt, y[1], y[2])), collapse=" & ")))
}
else {
cat(paste(block[i,], collapse=" & "), "\\\\ \n")
if (percentage != "none") {
cat(rep(" &", n.row.vars-1))
cat("\\%", gsub("NaN", "---", sprintf(fmt, pct[i, ])), sep=" & ")
}
}
if (percentage != "none") {
cat(" \\\\")
}
if (i < n-1) {
cat(sprintf("[%smm]\n", rev))
}
else if (i == n) {
if (end < nrow) {
cat(sprintf("\\cline{%i-%i}\n", sum(side[end+1,] == "")+1, fac*(m.col.vars[1]+1)+n.row.vars))
}
else {
cat(sprintf("%s\n", toprule))
}
}
else {
cat(sprintf("\\cline{%i-%i}\n", n.row.vars, fac*(m.col.vars[1]+1)+n.row.vars))
}
}
}
cat("\\end{tabular}\n",
"\\end{table}\n", sep="")
}
使用例
# x <- ftable(Survived ~ ., data = Titanic)
# a <- ftable(Survived ~ Sex + Class + Age, data = x)
# library(xtable)
# xtable(a, "タイタニックデータの集計(1)", "table1")
# xtable(ftable(Survived ~ Sex + Class, data = x), "タイタニックデータの集計(2)", "table2")
LaTeX でタイプセットすると以下のようになる。