在LaTeX

时间:2017-06-04 14:36:39

标签: r latex hmisc

> 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

我有一个包含3个问题和2个人​​口统计变量的data.frame。我已经编写了一个输出汇总表的函数。

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),告诉函数我要选择哪些问题。在我的例子中,我选择了问题1和2.我希望函数输出一个计数及其相应的比例。表格的最后一行是p值,它反映了问题与人口统计变量(性别或类型)之间的关联。

xtable(data.frame(tab))

调用上面的函数给出了以下LaTeX表:

enter image description here

我想要的是:

enter image description here

表中的条目在每个单元格中显示为count (proportion),而不是具有单独的比例列。有没有更有效的方法来做到这一点?在Hmisc中可能吗?

1 个答案:

答案 0 :(得分:0)

以下是使用knitr,xtable和tabularX包的答案。

tabularX包将确保文档的宽度由X列填充。使用tabular.environment = "tabularx"方法中的选项width="\\textwidth"print.xtable调用它,我使用选项align(xt)<-c("l","X","X","X","X"),以便我的X列宽度跨越页面的剩余宽度。< / p>

在您的示例中,您想要粘贴两个值(数字和概率),只需调用str_c(str_c(tt[, 1]," (",ptt[, 1],")")str_c()就像paste(),但默认情况下,分隔符为“” 。在创建data.frame时,重复唯一值“)”和“)”以匹配表的行数。

主要问题是最后一行只有两列。所以我使用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")

当我在函数内部执行此操作时,我返回两个元素的列表,第一个是表,第二个是add.to.row参数。

最后,我的表看起来像:

% 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}

产生

table with two different row length

这是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}