如何在R中为包含分类数据的列子集创建列联表(交叉表)?

时间:2010-08-19 01:12:31

标签: r crosstab

我有一个表格,其标题如下(我简化了它):

id, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10

其中除id之外的每一行都是一个分类变量。我们将类别命名为A,B,C,D,E。

我想为列的某些创建一个列联表,如下所示(为简洁起见,我没有在单元格中放置样本号)。获得总列/行会很棒,但不是强制性的,我可以稍后自己计算。

      a1  a2  a3  a4 Total
    ----------------------
    A|
    B|
    C|
    D|
    E|
Total|

因此,问题是如何基于R中的多个列创建交叉表?我用table()和xtabs()看过的例子只使用了一列。在我的例子中,列是相邻的,因此一个交叉表将汇总列a1..a4,另一个列为a5..a7,依此类推。我希望有一种优雅的方式来做到这一点。

我是程序员,但是R的新手。

提前谢谢。

2 个答案:

答案 0 :(得分:7)

为此目的,您的数据格式不正确。这是使用reshape包适当地重塑数据的一种方法。

library(reshape)
data.m <- melt(data, id = "id")

要计算所有级别的表格,并使用边距,您可以使用

cast(data.m, value ~ variable, margins = T)

对于子集,请使用data.m的相关子集。

答案 1 :(得分:3)

以下是使用基本R命令的方法。如果每列具有相同的因子级别,则不需要for循环,但循环将是一个良好的故障安全。

> set.seed(21)
> df <- data.frame(
+   id=1:20,
+   a1=sample(letters[1:4],20,TRUE),
+   a2=sample(letters[1:5],20,TRUE),
+   a3=sample(letters[2:5],20,TRUE),
+   a4=sample(letters[1:5],20,TRUE),
+   a5=sample(letters[1:5],20,TRUE),
+   a6=sample(letters[1:5],20,TRUE) )
> 
> for(i in 2:NCOL(df)) {
+   levels(df[,i]) <- list(a="a",b="b",c="c",d="d",e="e")
+ }
> 
> addmargins(mapply(table,df[,-1]))
    a1 a2 a3 a4 a5 a6 Sum
a    6  2  0  2  5  3  18
b    3  3  7  2  1  3  19
c    5  3  1  6  5  3  23
d    6  8  6  1  5  3  29
e    0  4  6  9  4  8  31
Sum 20 20 20 20 20 20 120