计数& xTable、Sweave、R、交叉表中的百分比
编辑:根据下面 aL3xa 的答案,我修改了下面的语法。不完美,但越来越接近。我仍然没有找到一种方法让 xtable 接受列或行的 \multicolumn{} 参数。 Hmisc 似乎也在幕后处理一些此类任务,但了解那里发生的事情似乎有点困难。有人对 Hmisc 中的 Latex 函数有经验吗?
ctab <- function(tab, dec = 2, margin = NULL) {
tab <- as.table(tab)
ptab <- paste(round(prop.table(tab, margin = margin) * 100, dec), "%", sep = "")
res <- matrix(NA, nrow = nrow(tab) , ncol = ncol(tab) * 2, byrow = TRUE)
oddc <- 1:ncol(tab) %% 2 == 1
evenc <- 1:ncol(tab) %% 2 == 0
res[,oddc ] <- tab
res[,evenc ] <- ptab
res <- as.table(res)
colnames(res) <- rep(colnames(tab), each = 2)
rownames(res) <- rownames(tab)
return(res)
}
我想创建一个针对 LaTeX 输出格式化的表,其中包含每列或变量的计数和百分比。我还没有找到解决这个问题的现成解决方案,但感觉我必须在某种程度上重新创造轮子。
我已经开发了一种用于直接制表的解决方案,但正在努力采用交叉制表的方法。
首先是一些示例数据:
#Generate sample data
dow <- sample(1:7, 100, replace=TRUE)
purp <- sample(1:4, 100, replace=TRUE)
dow <- factor(dow, 1:7, c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
purp <- factor(purp, 1:4, c("Business", "Commute", "Vacation", "Other"))
现在是工作的直接选项卡功能:
customTable <- function(var, capt = NULL){
counts <- table(var)
percs <- 100 * prop.table(counts)
print(
xtable(
cbind(
Count = counts
, Percent = percs
)
, caption = capt
, digits = c(0,0,2)
)
, caption.placement="top"
)
}
#Usage
customTable(dow, capt="Day of Week")
customTable(purp, capt="Trip Pupose")
有人对采用此功能进行交叉表(即按旅行目的进行星期几)有任何建议吗?这是我目前编写的内容,它不使用 xtable 库并且几乎可以工作,但不是动态的并且使用起来非常难看:
#Create table and percentages
a <- table(dow, purp)
b <- round(prop.table(a, 1),2)
#Column bind all of the counts & percentages together, this SHOULD become dynamic in future
d <- cbind( cbind(Count = a[,1],Percent = b[,1])
, cbind(Count = a[,2], Percent = b[,2])
, cbind(Count = a[,3], Percent = b[,3])
, cbind(Count = a[,4], Percent = b[,4])
)
#Ugly function that needs help, or scrapped for something else
crossTab <- function(title){
cat("\\begin{table}[ht]\n")
cat("\\begin{center}\n")
cat("\\caption{", title, "}\n", sep="")
cat("\\begin{tabular}{rllllllll}\n")
cat("\\hline\n")
cat("", cat("", paste("&\\multicolumn{2}{c}{",colnames(a), "}"), sep = ""), "\\\\\n", sep="")
c("&", cat("", colnames(d), "\\\\\n", sep=" & "))
cat("\\hline\n")
c("&", write.table(d, sep = " & ", eol="\\\\\n", quote=FALSE, col.names=FALSE))
cat("\\hline\n")
cat("\\end{tabular}\n")
cat("\\end{center}\n")
cat("\\end{table}\n")
}
crossTab(title = "Day of week BY Trip Purpose")
Edit: Building off of aL3xa's answer below, I've modified his syntax below. Not perfect, but getting closer. I still haven't found a way to make xtable accept \multicolumn{} arguments for columns or rows. It also appears that Hmisc handles some of these type of tasks behind the scenes, but it looks like a bit of an undertaking to understand what's going on there. Does anyone have experience with the latex function in Hmisc?
ctab <- function(tab, dec = 2, margin = NULL) {
tab <- as.table(tab)
ptab <- paste(round(prop.table(tab, margin = margin) * 100, dec), "%", sep = "")
res <- matrix(NA, nrow = nrow(tab) , ncol = ncol(tab) * 2, byrow = TRUE)
oddc <- 1:ncol(tab) %% 2 == 1
evenc <- 1:ncol(tab) %% 2 == 0
res[,oddc ] <- tab
res[,evenc ] <- ptab
res <- as.table(res)
colnames(res) <- rep(colnames(tab), each = 2)
rownames(res) <- rownames(tab)
return(res)
}
I would like to create a table formatted for LaTeX output that contains both the counts and percentages for each column or variable. I have not found a ready made solution to this problem, but feel I must be recreating the wheel to some extent.
I have developed a solution for straight tabulations, but am struggling with adopting something for a cross tabulation.
First some sample data:
#Generate sample data
dow <- sample(1:7, 100, replace=TRUE)
purp <- sample(1:4, 100, replace=TRUE)
dow <- factor(dow, 1:7, c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
purp <- factor(purp, 1:4, c("Business", "Commute", "Vacation", "Other"))
And now the working straight tab function:
customTable <- function(var, capt = NULL){
counts <- table(var)
percs <- 100 * prop.table(counts)
print(
xtable(
cbind(
Count = counts
, Percent = percs
)
, caption = capt
, digits = c(0,0,2)
)
, caption.placement="top"
)
}
#Usage
customTable(dow, capt="Day of Week")
customTable(purp, capt="Trip Pupose")
Does anyone have any suggestions for adopting this for cross tabulations (i.e. day of week BY trip purpose)? Here is what I've currently written, which does NOT use the xtable library and ALMOST works, but is not dynamic and is quite ugly to work with:
#Create table and percentages
a <- table(dow, purp)
b <- round(prop.table(a, 1),2)
#Column bind all of the counts & percentages together, this SHOULD become dynamic in future
d <- cbind( cbind(Count = a[,1],Percent = b[,1])
, cbind(Count = a[,2], Percent = b[,2])
, cbind(Count = a[,3], Percent = b[,3])
, cbind(Count = a[,4], Percent = b[,4])
)
#Ugly function that needs help, or scrapped for something else
crossTab <- function(title){
cat("\\begin{table}[ht]\n")
cat("\\begin{center}\n")
cat("\\caption{", title, "}\n", sep="")
cat("\\begin{tabular}{rllllllll}\n")
cat("\\hline\n")
cat("", cat("", paste("&\\multicolumn{2}{c}{",colnames(a), "}"), sep = ""), "\\\\\n", sep="")
c("&", cat("", colnames(d), "\\\\\n", sep=" & "))
cat("\\hline\n")
c("&", write.table(d, sep = " & ", eol="\\\\\n", quote=FALSE, col.names=FALSE))
cat("\\hline\n")
cat("\\end{tabular}\n")
cat("\\end{center}\n")
cat("\\end{table}\n")
}
crossTab(title = "Day of week BY Trip Purpose")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在 Tables 包中,只有一行:
使用 booktabs,您会得到以下内容(可以进一步自定义):
In the Tables-package it is one line:
Using booktabs, you get this (can be further customised):
很好的问题,这个问题困扰了我一段时间(这并不难,只是我太懒了......像往常一样)。然而……虽然这个问题很好,但恐怕你的方法却不是。有一个名为
xtable
的无价软件包,您可以(误)使用它。此外,这个问题太常见了 - 互联网上的某个地方很可能已经有一些现成的解决方案。有一天,我将一劳永逸地解决这个问题(我会将代码发布到 GitHub 上)。主要思想有点像这样:您想要一个单元格内的频率和/或百分比值(用 \ 分隔)或连续具有绝对和相对频率(或%)的行吗?我会选择第二个nd,所以我现在会发布一个“急救”解决方案:
现在尝试类似的操作:
确保加载了
xtable
包并使用print
(它是一个通用函数,因此您必须传递一个xtable
类对象)。抑制行名称很重要。我明天将优化这个 - 它应该与xtable
兼容。在我的时区,现在是凌晨 3 点,所以我将以这些话结束我的回答:干杯!
Great question, this one's bothering me for a while (it's not that hard, it's just me being lazy as hell... as usual). However... though the question's great, your approach, I'm afraid, isn't. There's priceless package called
xtable
that you can (mis)use. Besides, this issue is too common - there's a great chance that there's already some ready-made solution sitting somewhere on the Internets.One of these days I'm about to work it out once and for all (I'll post the code on GitHub). The main idea goes a little bit like this: would you like frequency and/or percentage values within one cell (separated by \) or rows with absolute and relative frequencies (or %) in succession? I'd go with the 2nd one, so I'll post a "first-aid" solution for now:
Now try something like:
Make sure you loaded
xtable
package and useprint
(it's a generic function, so you must pass axtable
classed object). It's important that you suppress the row names. I'll optimize this one tomorrow - it should bextable
compatible. It's 3AM in my time zone, so with these lines I'll end my answer:Cheers!
我无法弄清楚如何使用 xtable 生成多列标题,但我确实意识到我可以连接我的计数和列标题。出于打印目的,将百分比放入同一列中。不理想,但似乎完成了工作。这是我编写的函数:
可能不是最终产品,但确实允许参数具有一定的灵活性。在最基本的层面上,它只是
table()
的包装器,但也可以生成 LaTeX 格式的输出。以下是我最终在Sweave
文档中使用的内容:I wasn't able to figure out how to generate a multi column header using xtable, but I did realize that i could concatenate my counts & percentages into the same column for printing purposes. Not ideal, but seems to get the job done. Here's the function I've written:
Probably not the final product, but does allow for some flexibility in parameters. At the most basic level, is only a wrapper of
table()
but can also generate LaTeX formatted output as well. Here is what I ended up using in aSweave
document:将
multicolumn
与 Hmisc 包中的latex
结合使用也不错。这个最小的 Sweave 文档:为我生成这个:
显然,我已经硬编码了相当多的内容东西,并且可能有更灵活的方法来生成最终传递给
latex
的数据帧,但这至少应该为使用multicolum
提供一个开始。另外,有一个小问题,在组合计数和百分比来交替列时,我使用了 ggplot2 的 interleave 函数。那只是因为我懒。
Using
multicolumn
withlatex
from the Hmisc package isn't too bad. This minimal Sweave document:Produces this for me:
Obviously, I've hard-coded a fair bit of stuff, and there could be slicker ways to produce the data frame that you end up passing to
latex
, but this should at least give a start usingmulticolum
.Also, a slight gotcha, I've used ggplot2's
interleave
function when combining the counts and percentages to alternate the columns. That's just cause I'm lazy.这对你来说怎么样?
它没有给你很好的多列,而且我没有足够的 xtable 经验来弄清楚这是否可能。但是,如果您要编写自定义函数,您可以尝试对
df.print
的列名称进行操作。您甚至可以编写一个足够通用的代码来将各种方式的重铸数据帧作为输入。编辑:
只是想到了一个好办法来让你们更接近。创建 df.m 后
,现在每个单元格将包含 N / 百分比 值
How would this work for you?
It doesn't give you nice multicolumns, and I don't have enough experience with
xtable
to figure out if that's possible. However, if you're going to be writing custom functions, you might try one which operates over the column names ofdf.print
. You might be even able to write one sufficiently general to take all manner of recast data frames as input.Edit:
Just thought of a good solution to get you closer. After creating
df.m
Now, every cell will contain
N / percent
values我意识到这个线程有点旧,但是 reporttools 包中的 tableNominal() 函数可能提供您正在寻找的功能。
I realize this thread is a bit old, but the tableNominal() function in the reporttools package may provide the functionality you are looking for.