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

13

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

<code>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)
</code>

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

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

<code>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)
</code>

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

Тогда как мне добавить третью переменную в микс?

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

update Это привело меня туда, но это не красиво.

<code>aggregate(mpg ~ am+cyl+gear, mtcars,sum)
</code>

ура

Ваш Ответ

4   ответа
3

Я хотел бы добавить некоторую информацию к ответу Джоша О. Брайена. Пользователь может использовать агрегатную функцию или использовать в зависимости от вывода. Чтобы использовать более одной факторной переменной в 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

Теперь, если пользователь хочет получить тот же результат, что и агрегатная функция, но с использованием 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 могут быть сохранены или удалены в соответствии с требованиями бизнеса.

34

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 
Error: User Rate Limit ExceededftableError: User Rate Limit Exceeded
4

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
Error: User Rate Limit ExceededfillError: User Rate Limit ExceededdcastError: User Rate Limit Exceededfill = InfError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded"mpg"Error: User Rate Limit Exceededmeasure.varsError: User Rate Limit ExceededNAError: User Rate Limit Exceeded0Error: User Rate Limit Exceeded
7

что ответы уже на этот вопрос - фантастические варианты, но я хотел бы поделиться дополнительной опцией, основанной на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
Error: User Rate Limit Exceededstackoverflow.com/questions/24536154/what-does-mean-in-r
Error: User Rate Limit Exceeded

Похожие вопросы