Как получить трехстороннюю таблицу, отображающую среднее значение одной переменной в зависимости от всех комбинаций двух других переменных? - PullRequest
0 голосов
/ 01 ноября 2018

Мне нужна трехсторонняя таблица, отображающая среднее значение 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))

1 Ответ

0 голосов
/ 01 ноября 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...