在R中的同一个表中获取列数和比例

时间:2012-02-24 21:18:23

标签: r

如果有一个函数可以在同一个表中同时给出计数和列/总百分比?我可以查看两个表和reshape2,但没有看到这样做的选项。我举一个例子:

数据设置

n <- 100
x <- sample(letters[1:3], n, T)
y <- sample(letters[1:3], n, T)
d <- data.frame(x=x, y=y)

使用表格

这非常笨重,因为它要求我取消列表并重新组合。

> library(tables)
> (t1 <- tabular(x~y*(n=length), d))

   a  b  c 
 x n  n  n 
 a 13 14 11
 b  8 11 13
 c 10 12  8
> prop.table(matrix(unlist(t1),3,3), 1)
          [,1]      [,2]      [,3]
[1,] 0.3421053 0.3684211 0.2894737
[2,] 0.2500000 0.3437500 0.4062500
[3,] 0.3333333 0.4000000 0.2666667

使用Reshape2

这有点容易,但仍然不在一个。

> library(reshape2)
> (t2 <- acast(d, x~y, length))
Using y as value column: use value_var to override.
   a  b  c
a 13 14 11
b  8 11 13
c 10 12  8
> (t3 <- prop.table(t2,1))
          a         b         c
a 0.3421053 0.3684211 0.2894737
b 0.2500000 0.3437500 0.4062500
c 0.3333333 0.4000000 0.2666667

期望的输出

我真正想要的是看起来像这样的输出:

> structure(list(
+     a = data.frame(n=t2[,1], pct=t3[,1]),
+     b = data.frame(n=t2[,2], pct=t3[,2]),
+     c = data.frame(n=t2[,3], pct=t3[,3])), 
+   class = 'data.frame',
+   row.names = letters[1:3])
  a.n     a.pct b.n     b.pct c.n     c.pct
a  13 0.3421053  14 0.3684211  11 0.2894737
b   8 0.2500000  11 0.3437500  13 0.4062500
c  10 0.3333333  12 0.4000000   8 0.2666667

有没有办法用R轻松完成?

3 个答案:

答案 0 :(得分:3)

使用gmodles包中的CrossTable功能。

library(gmodels)

检查CrossTable

的参数
args(CrossTable)
function (x, y, digits = 3, max.width = 5, expected = FALSE, 
    prop.r = TRUE, prop.c = TRUE, prop.t = TRUE, prop.chisq = TRUE, 
    chisq = FALSE, fisher = FALSE, mcnemar = FALSE, resid = FALSE, 
    sresid = FALSE, asresid = FALSE, missing.include = FALSE, 
    format = c("SAS", "SPSS"), dnn = NULL, ...) 
NULL

申请CrossTable

CrossTable(x=d$x, y=d$y)



   Cell Contents
|-------------------------|
|                       N |
| Chi-square contribution |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|


Total Observations in Table:  100 


             | d$y 
         d$x |         a |         b |         c | Row Total | 
-------------|-----------|-----------|-----------|-----------|
           a |        13 |        12 |         8 |        33 | 
             |     0.182 |     0.306 |     0.924 |           | 
             |     0.394 |     0.364 |     0.242 |     0.330 | 
             |     0.371 |     0.387 |     0.235 |           | 
             |     0.130 |     0.120 |     0.080 |           | 
-------------|-----------|-----------|-----------|-----------|
           b |        13 |        11 |        18 |        42 | 
             |     0.197 |     0.313 |     0.969 |           | 
             |     0.310 |     0.262 |     0.429 |     0.420 | 
             |     0.371 |     0.355 |     0.529 |           | 
             |     0.130 |     0.110 |     0.180 |           | 
-------------|-----------|-----------|-----------|-----------|
           c |         9 |         8 |         8 |        25 | 
             |     0.007 |     0.008 |     0.029 |           | 
             |     0.360 |     0.320 |     0.320 |     0.250 | 
             |     0.257 |     0.258 |     0.235 |           | 
             |     0.090 |     0.080 |     0.080 |           | 
-------------|-----------|-----------|-----------|-----------|
Column Total |        35 |        31 |        34 |       100 | 
             |     0.350 |     0.310 |     0.340 |           | 
-------------|-----------|-----------|-----------|-----------|

答案 1 :(得分:3)

这是一种方法,您仍需要第二步,但它位于tabular命令之前,因此结果仍然是tabular对象。

n <- 100 
x <- sample(letters[1:3], n, T) 
y <- sample(letters[1:3], n, T) 
d <- data.frame(x=x, y=y) 
d$z <- 1/ave( rep(1,n), d$x, FUN=sum )

(t1 <- tabular(x~y*Heading()*z*((n=length) + (p=sum)), d))

答案 2 :(得分:2)

tbl <- with(d, table(x,y)  )
 pct.tbl <- prop.table(tbl)
 colnames(pct.tbl) <- paste("pct",colnames(pct.tbl), sep=".") 
# The next line constructs an interleaving index to rearrange the columns
 cbind(tbl, pct.tbl)[, c( matrix(1:(2*ncol(tbl)), nrow=2, byrow=TRUE) )]
#------
   a pct.a  b pct.b  c pct.c
a 11  0.11 10  0.10 12  0.12
b  6  0.06 11  0.11 11  0.11
c 12  0.12 11  0.11 16  0.16

进行交错的另一种方法是使用c来删除转置的矩阵序列

c( t( matrix(1:(2*ncol(tbl)), ncol=2) ) )
#[1] 1 4 2 5 3 6

如果您希望这些比例为列百分比,那么只需在2调用中的'tbl'参数后面加prop.table

 prop.table(tbl,2)
 #----------
   y
x           a         b         c
  a 0.3793103 0.3125000 0.3076923
  b 0.2068966 0.3437500 0.2820513
  c 0.4137931 0.3437500 0.4102564