如何获得一个显示一个变量的平均值的三向表,取决于两个其他变量的所有组合?

时间:2018-11-01 11:47:00

标签: r

我想要一个三向表,以显示ab的所有组合的c的平均值。

table()outer()分别给了我我想要的东西:

> with(df1, table(c, b))
    b
c    0 1
  5  1 1
  10 1 2
  15 3 2

> t(outer(0:1, c(5, 10, 15), Vectorize(function(x, y) 
+   with(df1, mean(a[b == x & c == y])))))
         [,1] [,2]
[1,] 17.00000 20.0
[2,] 17.00000 16.5
[3,] 16.66667 15.0

我该如何结合这些,最好是在基本的 R 解决方案中?

我尝试了ftable(),这给了我

> with(df1, ftable(c, a, b))
      b 0 1
c  a       
5  11   0 0
   13   0 0
   15   0 0
   17   1 0
   18   0 0
   19   0 0
   20   0 1
10 11   0 0
   13   0 0
   15   0 1
   17   1 0
   18   0 1
   19   0 0
   20   0 0
15 11   1 0
   13   0 1
   15   0 0
   17   0 1
   18   0 0
   19   1 0
   20   1 0

但是我想要的是这个

    b
c       0     1
  5    17    20
        1     1
  10   17  16.5
        1     2
  15 16.7    15
        3     2

数据:

set.seed(42)
df1 <- data.frame(a=sample(10:20, 10, replace = TRUE),
                  b=sample(0:1, 10, replace = TRUE),
                  c=sample(c(5, 10, 15), 10, replace = TRUE))

1 个答案:

答案 0 :(得分:1)

请注意,类table的对象并不是很特殊;他们只是具有此类和dimnames属性:

str(table(1:2, 2:3))
#  'table' int [1:2, 1:2] 1 0 0 1
#  - attr(*, "dimnames")=List of 2
#   ..$ : chr [1:2] "1" "2"
#   ..$ : chr [1:2] "2" "3"

因此,实际上很容易将结果转换为表格:

tmp <- t(outer(0:1, c(5, 10, 15), Vectorize(function(x, y) 
  with(df1, mean(a[b == x & c == y])))))
class(tmp) <- "table"
dimnames(tmp) <- list(c = c("5", "10", "15"), b = c("0", "1"))
tmp
#     b
# c           0        1
#   5  17.00000 20.00000
#   10 17.00000 16.50000
#   15 16.66667 15.00000

但是,除了所有这些,您还可以运行

xtabs(a ~ b + c, data = aggregate(a ~ b + c, data = df1, mean))
#    c
# b          5       10       15
#   0 17.00000 17.00000 16.66667
#   1 20.00000 16.50000 15.00000

最后,要在下方添加另一行频率,您可以运行

out <- do.call(rbind, lapply(c(mean, length), function(fun)
  xtabs(a ~ b + c, data = aggregate(a ~ b + c, data = df1, fun))))
out[order(rownames(out)), ]
#    5   10       15
# 0 17 17.0 16.66667
# 0  1  1.0  3.00000
# 1 20 16.5 15.00000
# 1  1  2.0  2.00000

很明显,您现在可以继续添加除meanlength之外的其他功能。

如果您希望cb可见或某些行名为空,则可以像上面那样类似地分配dimnames(out)