R 如何获得一个三向表,根据其他两个变量的所有组合显示一个变量的平均值?
我想要一个三向表,显示所有R 如何获得一个三向表,根据其他两个变量的所有组合显示一个变量的平均值?,r,R,我想要一个三向表,显示所有b和c组合的a平均值 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
b
和c
组合的a
平均值
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注意类表的对象并不是真正特殊的;它们只有这个类和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
最后,要在右下方添加另一行频率,您可以运行
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
很好,到目前为止,我从未使用过xtabs()。但我仍然需要有频率的子行。我可以根据您的代码使用xtabs(a~b+c,data=aggregate(a~b+c,data=df1,length))
获取它们。现在我们必须把它们结合起来c(平均值,长度)
但是不起作用。我将对此进行研究,但除了示例输出中没有提及频率之外,您对频率提出了任何质疑,这大大改变了问题,使其不再仅显示平均值。鉴于表
的这种简单性质,我们可以简单地rbind
它们并对行进行排序。剩下的就是您想要对这些行执行的操作。我不认为有更直接的解决方案,至少在BaseR中是这样。
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