Подтвердить что ты не робот

Сводная статистика по двум или более факторам?

Это лучше всего иллюстрируется примером

str(mtcars)
mtcars$gear <- factor(mtcars$gear, labels=c("three","four","five"))
mtcars$cyl <- factor(mtcars$cyl, labels=c("four","six","eight"))
mtcars$am <- factor(mtcars$am, labels=c("manual","auto")
str(mtcars)
tapply(mtcars$mpg, mtcars$gear, sum)

Это дает мне сумму mpg на каждую передачу. Но скажу, что мне нужна таблица 3x3 с шестеркой сверху и цилиндром вниз, и 9 ячеек с двузначными суммами, как бы я получил это "умно".

Я мог бы пойти.

tapply(mtcars$mpg[mtcars$cyl=="four"], mtcars$gear[mtcars$cyl=="four"], sum)
tapply(mtcars$mpg[mtcars$cyl=="six"], mtcars$gear[mtcars$cyl=="six"], sum)
tapply(mtcars$mpg[mtcars$cyl=="eight"], mtcars$gear[mtcars$cyl=="eight"], sum)

Это кажется громоздким.

Затем, как бы я привел 3-ю переменную в миксе?

Это несколько в пространстве, о котором я думаю. Сводная статистика с использованием ddply

update Это меня туда, но это не очень.

aggregate(mpg ~ am+cyl+gear, mtcars,sum)

Приветствия

4b9b3361

Ответ 1

Как насчет этого, все еще используя tapply()? Это более универсально, чем вы знали!

with(mtcars, tapply(mpg, list(cyl, gear), sum))
#       three  four five
# four   21.5 215.4 56.4
# six    39.5  79.0 19.7
# eight 180.6    NA 30.8

Или, если вы хотите, чтобы напечатанный вывод был немного более интерпретируемым:

with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum))

Если вы хотите использовать более двух перекрестно-классифицирующих переменных, идея точно такая же. Затем результаты будут возвращены в 3-мерном массиве:

A <- with(mtcars, tapply(mpg, list(cyl, gear, carb), sum))

dim(A)
# [1] 3 3 6
lapply(1:6, function(i) A[,,i]) # To convert results to a list of matrices

# But eventually, the curse of dimensionality will begin to kick in...
table(is.na(A))
# FALSE  TRUE 
#    12    42 

Ответ 2

Я думаю, что ответы уже на этот вопрос являются фантастическими вариантами, но я хотел поделиться дополнительным вариантом, основанным на пакете dplyr (это пришло мне в голову, потому что я преподаю класс прямо сейчас, где мы используем dplyr для манипуляций с данными, поэтому я хотел не вводить учащихся в специализированные базовые функции R, такие как tapply или aggregate).

Вы можете группировать столько переменных, сколько хотите, используя функцию group_by, а затем суммировать информацию из этих групп с помощью summarize. Я думаю, что этот код более читабельен для новичков R, чем интерфейс на основе формул aggregate, что дает идентичные результаты:

library(dplyr)
mtcars %>%
  group_by(am, cyl, gear) %>%
  summarize(mpg=sum(mpg))
#       am   cyl  gear   mpg
#    (dbl) (dbl) (dbl) (dbl)
# 1      0     4     3  21.5
# 2      0     4     4  47.2
# 3      0     6     3  39.5
# 4      0     6     4  37.0
# 5      0     8     3 180.6
# 6      1     4     4 168.2
# 7      1     4     5  56.4
# 8      1     6     4  42.0
# 9      1     6     5  19.7
# 10     1     8     5  30.8

С двумя переменными вы можете суммировать с одной переменной в строках, а другую в столбцах, добавив вызов функции spread из пакета tidyr:

library(dplyr)
library(tidyr)
mtcars %>%
  group_by(cyl, gear) %>%
  summarize(mpg=sum(mpg)) %>%
  spread(gear, mpg)
#     cyl     3     4     5
#   (dbl) (dbl) (dbl) (dbl)
# 1     4  21.5 215.4  56.4
# 2     6  39.5  79.0  19.7
# 3     8 180.6    NA  30.8

Ответ 3

Мне нравится Josh для этого, но reshape2 также может обеспечить хорошую структуру для этих проблем:

library(reshape2)

#use subset to only grab the variables of interest...
mtcars.m <- melt(subset(mtcars, select = c("mpg", "gear", "cyl")), measure.vars="mpg")
#cast into appropriate format
dcast(mtcars.m, cyl ~ gear, fun.aggregate=sum, value.var="value")

   cyl three  four five
1  four  21.5 215.4 56.4
2   six  39.5  79.0 19.7
3 eight 180.6   0.0 30.8

Ответ 4

Ответ содержит тот же результат, используя функцию tapply и aggregate.

Я хотел бы добавить некоторую информацию в ответ Джоша О'Брайена. Пользователь может либо использовать функцию агрегата, либо использовать в зависимости от вывода. Чтобы использовать более одной фактор-переменной в tapply, можно использовать метод, показанный Джошем.

Загрузка набора данных

data("mtcars")

Использование tapply

with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum))

Вывод кода выше

        Gear#
Cylinder#     3     4    5
    4     21.5 215.4 56.4
    6     39.5  79.0 19.7
    8    180.6    NA 30.8

Использование агрегатной функции

with(mtcars, aggregate(mpg, list(Cylinder = cyl, Gear =  gear), sum))

Вывод агрегатной функции

    Cylinder Gear  x
1        4    3  21.5
2        6    3  39.5
3        8    3 180.6
4        4    4 215.4
5        6    4  79.0
6        4    5  56.4
7        6    5  19.7
8        8    5  30.8

Теперь, если пользователь хочет получить тот же результат, что и функция aggregate, но используя tapply.

as.data.frame(as.table(with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear),
sum))))

Выход функции tapply

   Cylinder. Gear.  Freq
1         4     3  21.5
2         6     3  39.5
3         8     3 180.6
4         4     4 215.4
5         6     4  79.0
6         8     4    NA
7         4     5  56.4
8         6     5  19.7
9         8     5  30.8

NA может храниться или удаляться в соответствии с требованиями бизнеса.