我想要一个三向表,以显示a
和b
的所有组合的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))
答案 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
很明显,您现在可以继续添加除mean
和length
之外的其他功能。
如果您希望c
和b
可见或某些行名为空,则可以像上面那样类似地分配dimnames(out)
。