【发布时间】:2010-04-02 13:06:16
【问题描述】:
如果您有 2 个交叉分类变量,您可以使用 rowSums 和 colSums 在 xtabs 输出上生成保证金总计。但是如果你有 3 个分类变量(即每个子表中的边距总计)怎么办?
【问题讨论】:
标签: r
如果您有 2 个交叉分类变量,您可以使用 rowSums 和 colSums 在 xtabs 输出上生成保证金总计。但是如果你有 3 个分类变量(即每个子表中的边距总计)怎么办?
【问题讨论】:
标签: r
Aniko 在评论中提到了这一点,但从未作为答案提供。
我独立发现了这个,然后在评论中注意到它在这里,所以感谢 Aniko 首先得到它。
addmargins 是答案:
对于给定的表格,可以指定要分类的因素中的哪一个 扩展一个或多个级别以保存要计算的保证金。一个可能 例如在第一维和中位数上形成总和和均值 在第二个。结果表将有两个额外的级别 对于第一个维度和第二个额外的级别。这 默认是对表格中的所有边距求和。其他可能性 可能会给出取决于边距的顺序的结果 计算。这在函数的打印输出中被标记。
【讨论】:
一般方法是使用apply 函数,但特别是对于总计,margin.table 函数可能更方便:
#create 3 factors
a <- gl(2,4, length=20)
b <- gl(3,2, length=20)
d <- gl(4,2, length=20)
# table
tt <- xtabs(~a+b+d)
# marginal sums
margin.table(tt, 1)
apply(tt, 1, sum) #same answer
#multi-way margins
margin.table(tt, 1:2)
apply(tt, 1:2, sum) #same answer
【讨论】:
如果你没有绑定到 xtabs,Deducer 包有一些很好的列联表功能:
> a <- gl(2,4, length=20)
> b <- gl(3,2, length=20)
> d <- rnorm(20)>0
> dat <- data.frame(a,b,d)
> tables<-contingency.tables(
+ row.vars=a,
+ col.vars=b,
+ stratum.var=d,data=dat)
> tables
================================================================================
==================================================
========== Table: a by b ==========
| -- Stratum = FALSE --
| b
a | 1 | 2 | 3 | Row Total |
-----------------------|-----------|-----------|-----------|-----------|
1 Count | 2 | 2 | 1 | 5 |
Row % | 40.000% | 40.000% | 20.000% | 55.556% |
Column % | 40.000% | 100.000% | 50.000% | |
Total % | 22.222% | 22.222% | 11.111% | |
-----------------------|-----------|-----------|-----------|-----------|
2 Count | 3 | 0 | 1 | 4 |
Row % | 75.000% | 0.000% | 25.000% | 44.444% |
Column % | 60.000% | 0.000% | 50.000% | |
Total % | 33.333% | 0.000% | 11.111% | |
-----------------------|-----------|-----------|-----------|-----------|
Column Total | 5 | 2 | 2 | 9 |
Column % | 55.556% | 22.222% | 22.222% | |
| -- Stratum = TRUE --
| b
a | 1 | 2 | 3 | Row Total |
-----------------------|-----------|-----------|-----------|-----------|
1 Count | 2 | 2 | 3 | 7 |
Row % | 28.571% | 28.571% | 42.857% | 63.636% |
Column % | 66.667% | 50.000% | 75.000% | |
Total % | 18.182% | 18.182% | 27.273% | |
-----------------------|-----------|-----------|-----------|-----------|
2 Count | 1 | 2 | 1 | 4 |
Row % | 25.000% | 50.000% | 25.000% | 36.364% |
Column % | 33.333% | 50.000% | 25.000% | |
Total % | 9.091% | 18.182% | 9.091% | |
-----------------------|-----------|-----------|-----------|-----------|
Column Total | 3 | 4 | 4 | 11 |
Column % | 27.273% | 36.364% | 36.364% | |
================================================================================
【讨论】:
(如果我理解正确的话)你可以使用 ddply:
ff <- data.frame(f1=c("a", "b", "b", "b", "b", "b", "b"), f2=c("p", "p", "p", "q", "q", "q", "q"), f3=c("x","x","x","x","y", "y", "y"), val=c(1:7))
ddply(ff, .(f1), numcolwise(sum))
ddply(ff, .(f2), numcolwise(sum))
ddply(ff, .(f3), numcolwise(sum))
【讨论】:
上面的评论不起作用。感谢您的回答,但他们没有达到我的预期 - 每个子组中的个人总数。
经过一番挖掘,我发现本例中的 xtabs 输出是一个 3 维数组,并编写了以下函数来达到我想要的结果(注意它不完整,但到目前为止适用于列总计):
xtabTotals <- function(tabs,margin=1)
# takes a 3 dimensional xtabs array and performs margin total on each sub table
# only doing column margins so far
{
out <- array(0,dim(tabs)+c(1,0,0))
dnout <- dimnames(tabs)
dnout[[1]] <- c(dnout[[1]],"Total")
dimnames(out) <- dnout
for (i in 1:dim(tabs)[3])
{
out[,,i] <- rbind(tabs[,,i],colSums(tabs[,,i]))
}
out
}
【讨论】:
addmargins?