Обратите внимание, что объекты класса 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)
, как указано выше.