在 LaTeX 中生成应急摘要 table
Generating contingency summary table in LaTeX
> dput(mydat)
structure(list(Q1 = c(0, 1, NA, 1), Q2 = c(0, 1, 1, 1), Q3 = c(1,
NA, 1, 1), Gender = structure(c(2L, 2L, 1L, 1L), .Label = c("F",
"M"), class = "factor"), Type = c("A", "A", "A", "B")), .Names = c("Q1",
"Q2", "Q3", "Gender", "Type"), row.names = c(NA, -4L), class = "data.frame")
> mydat
Q1 Q2 Q3 Gender Type
1 0 0 1 M A
2 1 1 NA M A
3 NA 1 1 F A
4 1 1 1 F B
我有一个 data.frame,其中包含 3 个问题和 2 个人口统计变量。我写了一个函数来输出摘要 table.
myfun <- function(from, to){
tt = t(rowsum(mydat[from:to], mydat$Gender, na.rm = TRUE))
ptt = prop.table(tt, 2)
fish = fisher.test(tt, simulate.p.value = TRUE)
tt2 = t(rowsum(mydat[from:to], mydat$Type, na.rm = TRUE))
ptt2 = prop.table(tt2, 2)
fish2 = fisher.test(tt2, simulate.p.value = TRUE)
list(rbind(cbind(Female = tt[, 1], ptt[, 1], Male = tt[, 2], ptt[, 2],
A = tt2[, 1], ptt2[, 1], B = tt2[, 2], ptt2[, 2]),
c(fish$p.value, NA, NA, NA, fish2$p.value, NA, NA, NA)))
}
tab = myfun(1, 2)
>tab
[[1]]
Female Male A B
Q1 1 0.3333333 1 0.5 1 0.3333333 1 0.5
Q2 2 0.6666667 1 0.5 2 0.6666667 1 0.5
1 NA NA NA 1 NA NA NA
此函数接受 2 个参数(from、to),告诉函数我想要 select 哪些问题。在我的示例中,我 select 编辑了问题 1 和 2。我希望该函数输出一个计数及其相应的比例。 table 的最后一行是反映问题与人口统计变量(性别或类型)之间关联的 p 值。
xtable(data.frame(tab))
调用上述函数得到以下 LaTeX table:
我想要的是:
其中 table 中的条目在每个单元格中显示为 count (proportion)
,而不是为比例单独列一列。有没有更有效的方法来做到这一点?也许在 Hmisc 中?
这是使用 knitr、xtable 和 tabularX 包的答案。
tabularX 包将确保文档的宽度由 X 列填充。它在 print.xtable
方法中使用选项 tabular.environment = "tabularx"
和 width="\textwidth"
调用,我使用选项 align(xt)<-c("l","X","X","X","X")
以便我的 X 列宽度跨越页面的剩余宽度。
在您的示例中,您想粘贴两个值(数字和概率),这只需调用 str_c(str_c(tt[, 1]," (",ptt[, 1],")")
即可完成,str_c()
类似于 paste()
,但默认情况下分隔符是“”。创建 data.frame 时,将重复唯一值“)”和“)”以匹配 table.
的行数
主要问题是最后一行只有两列。所以我使用 xtable 的 add.to.row
参数来定义习惯行。我指定要在哪一行添加自定义值,这里是最后一行(第 2 行)因此 addtorow$pos[[1]] <- 2
,然后我添加一个参数说明该行将跨越两列。
addtorow$command <- str_c(" p-Value & \multicolumn{2}{c}{",fish$p.value,"} & \multicolumn{2}{c}{", fish2$p.value,"} \\\n")
当我在函数内部执行此操作时,我 return 一个包含两个元素的列表,第一个是 table,第二个是 add.to.row 参数。
最后,我的 table 看起来像:
% latex table generated in R 3.4.2 by xtable 1.8-2 package
% Mon Oct 30 21:50:04 2017
\begin{table}[ht]
\centering
\begin{tabularx}{\textwidth}{lXXXX}
\hline
& Female & Male & A & B \
\hline
1 & 1 (0.33) & 1 (0.5) & 1 (0.33) & 1 (0.5) \
2 & 2 (0.67) & 1 (0.5) & 2 (0.67) & 1 (0.5) \
p-Value & \multicolumn{2}{c}{1} & \multicolumn{2}{c}{1} \
\hline
\end{tabularx}
\end{table}
产生
这里是 knitr 代码:
\documentclass{article}
\title{Test example for table with different row length}
\usepackage{tabularx}
\date{} % no date
\begin{document}
\maketitle{}
<<init, echo = FALSE, results = 'hide'>>=
require(stringr)
require(xtable)
@
<<table_example, echo = FALSE, results = 'hide'>>=
require(stringr)
require(xtable)
mydat <- structure(list(Q1 = c(0, 1, NA, 1), Q2 = c(0, 1, 1, 1), Q3 = c(1, NA, 1,
1), Gender = structure(c(2L, 2L, 1L, 1L), .Label = c("F", "M"), class = "factor"),
Type = c("A", "A", "A", "B")), .Names = c("Q1", "Q2", "Q3", "Gender", "Type"),
row.names = c(NA, -4L), class = "data.frame")
myfun <- function(from, to) {
tt <- t(rowsum(mydat[, from:to], mydat$Gender, na.rm = TRUE))
ptt <- round(prop.table(tt, 2), 2)
fish <- fisher.test(tt, simulate.p.value = TRUE)
tt2 <- t(rowsum(mydat[, from:to], mydat$Type, na.rm = TRUE))
ptt2 <- round(prop.table(tt2, 2), 2)
fish2 <- fisher.test(tt2, simulate.p.value = TRUE)
df <- data.frame(Female = str_c(tt[, 1], " (", ptt[, 1], ")"), Male = str_c(tt[,
2], " (", ptt[, 2], ")"), A = str_c(tt2[, 1], " (", ptt2[, 1], ")"), B = str_c(tt2[,
2], " (", ptt2[, 2], ")"))
addtorow <- list()
addtorow$pos <- list()
addtorow$pos[[1]] <- 2
addtorow$command <- str_c(" p-Value & \multicolumn{2}{c}{", fish$p.value, "} & \multicolumn{2}{c}{",
fish2$p.value, "} \\\n")
return(list(df = df, addtorow = addtorow))
}
tab = myfun(1, 2)$df
addtorow = myfun(1, 2)$addtorow
xt <- xtable(tab)
align(xt) <- c("l", "X", "X", "X", "X")
print.xtable(x = xt, file = "test_table_out.tex", tabular.environment = "tabularx",
width = "\textwidth", add.to.row = addtorow)
@
\input{test_table_out.tex}
\end{document}
> dput(mydat)
structure(list(Q1 = c(0, 1, NA, 1), Q2 = c(0, 1, 1, 1), Q3 = c(1,
NA, 1, 1), Gender = structure(c(2L, 2L, 1L, 1L), .Label = c("F",
"M"), class = "factor"), Type = c("A", "A", "A", "B")), .Names = c("Q1",
"Q2", "Q3", "Gender", "Type"), row.names = c(NA, -4L), class = "data.frame")
> mydat
Q1 Q2 Q3 Gender Type
1 0 0 1 M A
2 1 1 NA M A
3 NA 1 1 F A
4 1 1 1 F B
我有一个 data.frame,其中包含 3 个问题和 2 个人口统计变量。我写了一个函数来输出摘要 table.
myfun <- function(from, to){
tt = t(rowsum(mydat[from:to], mydat$Gender, na.rm = TRUE))
ptt = prop.table(tt, 2)
fish = fisher.test(tt, simulate.p.value = TRUE)
tt2 = t(rowsum(mydat[from:to], mydat$Type, na.rm = TRUE))
ptt2 = prop.table(tt2, 2)
fish2 = fisher.test(tt2, simulate.p.value = TRUE)
list(rbind(cbind(Female = tt[, 1], ptt[, 1], Male = tt[, 2], ptt[, 2],
A = tt2[, 1], ptt2[, 1], B = tt2[, 2], ptt2[, 2]),
c(fish$p.value, NA, NA, NA, fish2$p.value, NA, NA, NA)))
}
tab = myfun(1, 2)
>tab
[[1]]
Female Male A B
Q1 1 0.3333333 1 0.5 1 0.3333333 1 0.5
Q2 2 0.6666667 1 0.5 2 0.6666667 1 0.5
1 NA NA NA 1 NA NA NA
此函数接受 2 个参数(from、to),告诉函数我想要 select 哪些问题。在我的示例中,我 select 编辑了问题 1 和 2。我希望该函数输出一个计数及其相应的比例。 table 的最后一行是反映问题与人口统计变量(性别或类型)之间关联的 p 值。
xtable(data.frame(tab))
调用上述函数得到以下 LaTeX table:
我想要的是:
其中 table 中的条目在每个单元格中显示为 count (proportion)
,而不是为比例单独列一列。有没有更有效的方法来做到这一点?也许在 Hmisc 中?
这是使用 knitr、xtable 和 tabularX 包的答案。
tabularX 包将确保文档的宽度由 X 列填充。它在 print.xtable
方法中使用选项 tabular.environment = "tabularx"
和 width="\textwidth"
调用,我使用选项 align(xt)<-c("l","X","X","X","X")
以便我的 X 列宽度跨越页面的剩余宽度。
在您的示例中,您想粘贴两个值(数字和概率),这只需调用 str_c(str_c(tt[, 1]," (",ptt[, 1],")")
即可完成,str_c()
类似于 paste()
,但默认情况下分隔符是“”。创建 data.frame 时,将重复唯一值“)”和“)”以匹配 table.
主要问题是最后一行只有两列。所以我使用 xtable 的 add.to.row
参数来定义习惯行。我指定要在哪一行添加自定义值,这里是最后一行(第 2 行)因此 addtorow$pos[[1]] <- 2
,然后我添加一个参数说明该行将跨越两列。
addtorow$command <- str_c(" p-Value & \multicolumn{2}{c}{",fish$p.value,"} & \multicolumn{2}{c}{", fish2$p.value,"} \\\n")
当我在函数内部执行此操作时,我 return 一个包含两个元素的列表,第一个是 table,第二个是 add.to.row 参数。
最后,我的 table 看起来像:
% latex table generated in R 3.4.2 by xtable 1.8-2 package
% Mon Oct 30 21:50:04 2017
\begin{table}[ht]
\centering
\begin{tabularx}{\textwidth}{lXXXX}
\hline
& Female & Male & A & B \
\hline
1 & 1 (0.33) & 1 (0.5) & 1 (0.33) & 1 (0.5) \
2 & 2 (0.67) & 1 (0.5) & 2 (0.67) & 1 (0.5) \
p-Value & \multicolumn{2}{c}{1} & \multicolumn{2}{c}{1} \
\hline
\end{tabularx}
\end{table}
产生
这里是 knitr 代码:
\documentclass{article}
\title{Test example for table with different row length}
\usepackage{tabularx}
\date{} % no date
\begin{document}
\maketitle{}
<<init, echo = FALSE, results = 'hide'>>=
require(stringr)
require(xtable)
@
<<table_example, echo = FALSE, results = 'hide'>>=
require(stringr)
require(xtable)
mydat <- structure(list(Q1 = c(0, 1, NA, 1), Q2 = c(0, 1, 1, 1), Q3 = c(1, NA, 1,
1), Gender = structure(c(2L, 2L, 1L, 1L), .Label = c("F", "M"), class = "factor"),
Type = c("A", "A", "A", "B")), .Names = c("Q1", "Q2", "Q3", "Gender", "Type"),
row.names = c(NA, -4L), class = "data.frame")
myfun <- function(from, to) {
tt <- t(rowsum(mydat[, from:to], mydat$Gender, na.rm = TRUE))
ptt <- round(prop.table(tt, 2), 2)
fish <- fisher.test(tt, simulate.p.value = TRUE)
tt2 <- t(rowsum(mydat[, from:to], mydat$Type, na.rm = TRUE))
ptt2 <- round(prop.table(tt2, 2), 2)
fish2 <- fisher.test(tt2, simulate.p.value = TRUE)
df <- data.frame(Female = str_c(tt[, 1], " (", ptt[, 1], ")"), Male = str_c(tt[,
2], " (", ptt[, 2], ")"), A = str_c(tt2[, 1], " (", ptt2[, 1], ")"), B = str_c(tt2[,
2], " (", ptt2[, 2], ")"))
addtorow <- list()
addtorow$pos <- list()
addtorow$pos[[1]] <- 2
addtorow$command <- str_c(" p-Value & \multicolumn{2}{c}{", fish$p.value, "} & \multicolumn{2}{c}{",
fish2$p.value, "} \\\n")
return(list(df = df, addtorow = addtorow))
}
tab = myfun(1, 2)$df
addtorow = myfun(1, 2)$addtorow
xt <- xtable(tab)
align(xt) <- c("l", "X", "X", "X", "X")
print.xtable(x = xt, file = "test_table_out.tex", tabular.environment = "tabularx",
width = "\textwidth", add.to.row = addtorow)
@
\input{test_table_out.tex}
\end{document}