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

Допустим, у меня есть два столбца данных. Первый содержит такие категории, как «Первый», «Второй», «Третий» и т. Д. Во втором есть числа, которые представляют количество раз, когда я видел «Первое».

Например:

Category Frequency First 10 First 15 First 5 Second 2 Third 14 Third 20 Second 3 

Я хочу сортировать данные по категориям и суммировать частоты:

 Category Frequency First 30 Second 5 Third 34 

Как мне это сделать в R?

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

 aggregate(x$Frequency, by=list(Category=x$Category), FUN=sum) Category x 1 First 30 2 Second 5 3 Third 34 

(вложение комментария @thelatemail), aggregate имеет интерфейс формулы

 aggregate(Frequency ~ Category, x, sum) 

Или, если вы хотите объединить несколько столбцов, вы можете использовать . обозначение (работает и для одного столбца)

 aggregate(. ~ Category, x, sum) 

или tapply :

 tapply(x$Frequency, x$Category, FUN=sum) First Second Third 30 5 34 

Используя эти данные:

 x <- data.frame(Category=factor(c("First", "First", "First", "Second", "Third", "Third", "Second")), Frequency=c(10,15,5,2,14,20,3)) 

Совсем недавно вы также можете использовать пакет dplyr для этой цели:

 library(dplyr) x %>% group_by(Category) %>% summarise(Frequency = sum(Frequency)) #Source: local data frame [3 x 2] # # Category Frequency #1 First 30 #2 Second 5 #3 Third 34 

Или для нескольких суммарных столбцов (работает с одним столбцом):

 x %>% group_by(Category) %>% summarise_each(funs(sum)) 

Обновление для dplyr> = 0.5: summarise_each было заменено на summarise_all , summarise_at и summarise_if в функции dplyr.

Или, если у вас есть несколько столбцов для группировки, вы можете указать их все в group_by разделенных запятыми:

 mtcars %>% group_by(cyl, gear) %>% # multiple group columns summarise(max_hp = max(hp), mean_mpg = mean(mpg)) # multiple summary columns 

Для получения дополнительной информации, включая оператора %>% , см. Введение в dplyr .

Ответ, предоставленный rcs, работает и прост. Однако, если вы работаете с более крупными наборами данных и нуждаетесь в повышении производительности, существует более быстрая альтернатива:

 library(data.table) data = data.table(Category=c("First","First","First","Second","Third", "Third", "Second"), Frequency=c(10,15,5,2,14,20,3)) data[, sum(Frequency), by = Category] # Category V1 # 1: First 30 # 2: Second 5 # 3: Third 34 system.time(data[, sum(Frequency), by = Category] ) # user system elapsed # 0.008 0.001 0.009 

Давайте сравним это с тем же, используя data.frame и выше:

 data = data.frame(Category=c("First","First","First","Second","Third", "Third", "Second"), Frequency=c(10,15,5,2,14,20,3)) system.time(aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum)) # user system elapsed # 0.008 0.000 0.015 

И если вы хотите сохранить столбец, это синтаксис:

 data[,list(Frequency=sum(Frequency)),by=Category] # Category Frequency # 1: First 30 # 2: Second 5 # 3: Third 34 

Разница станет более заметной с более крупными наборами данных, как показывает следующий код:

 data = data.table(Category=rep(c("First", "Second", "Third"), 100000), Frequency=rnorm(100000)) system.time( data[,sum(Frequency),by=Category] ) # user system elapsed # 0.055 0.004 0.059 data = data.frame(Category=rep(c("First", "Second", "Third"), 100000), Frequency=rnorm(100000)) system.time( aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum) ) # user system elapsed # 0.287 0.010 0.296 

Для множественных агрегаций вы можете комбинировать lapply и .SD следующим образом

 data[, lapply(.SD, sum), by = Category] # Category Frequency # 1: First 30 # 2: Second 5 # 3: Third 34 

Это несколько связано с этим вопросом .

Вы также можете использовать функцию by () :

 x2 <- by(x$Frequency, x$Category, sum) do.call(rbind,as.list(x2)) 

Эти другие пакеты (plyr, reshape) имеют преимущество в возвращении data.frame, но его стоит познакомиться с помощью (), поскольку это базовая функция.

 library(plyr) ddply(tbl, .(Category), summarise, sum = sum(Frequency)) 

Несколько лет спустя просто добавить еще одно простое базовое решение R, которое по какой-то причине xtabs здесь – xtabs

 xtabs(Frequency ~ Category, df) # Category # First Second Third # 30 5 34 

Или, если хотите вернуть данные.

 as.data.frame(xtabs(Frequency ~ Category, df)) # Category Freq # 1 First 30 # 2 Second 5 # 3 Third 34 

Просто добавьте третий вариант:

 require(doBy) summaryBy(Frequency~Category, data=yourdataframe, FUN=sum) 

EDIT: это очень старый ответ. Теперь я бы рекомендовал использовать group_by и суммировать из dplyr, как в ответе @docendo.

Хотя я недавно стал dplyr в dplyr для большинства этих типов операций, пакет sqldf по-прежнему очень хорош (и IMHO более читабельным) для некоторых вещей.

Вот пример того, как можно ответить на этот вопрос с помощью sqldf

 x <- data.frame(Category=factor(c("First", "First", "First", "Second", "Third", "Third", "Second")), Frequency=c(10,15,5,2,14,20,3)) sqldf("select Category ,sum(Frequency) as Frequency from x group by Category") ## Category Frequency ## 1 First 30 ## 2 Second 5 ## 3 Third 34 

Если x – это кадр данных с вашими данными, то следующее будет делать то, что вы хотите:

 require(reshape) recast(x, Category ~ ., fun.aggregate=sum) 

используя cast вместо recast (примечание 'Frequency' теперь 'value' )

 df <- data.frame(Category = c("First","First","First","Second","Third","Third","Second") , value = c(10,15,5,2,14,20,3)) install.packages("reshape") result<-cast(df, Category ~ . ,fun.aggregate=sum) 

получить:

 Category (all) First 30 Second 5 Third 34 
  • c ++ sort с structs
  • Сортировка массива объектов SimpleXML
  • Для чего нужен пузырь?
  • Как отсортировать массив с помощью специализированного компаратора?
  • Как отсортировать список объектов по определенному полю в C #?
  • Как использовать std :: sort для сортировки массива в C ++
  • Как я могу отсортировать ArrayList строк в Java?
  • Быстрая производительность: сортировка массивов
  • Почему java.lang.Number не реализует Comparable?
  • Есть ли поддержка в C ++ / STL для сортировки объектов по атрибуту?
  • Почему quicksort более популярен, чем сортировка radix?
  • Interesting Posts

    Зеленые мерцающие пиксели, которые движутся с черными изображениями

    Разница между показателями GiST и GIN

    Является ли отключение жестких дисков вредным?

    Правильный способ отключения индексирования в Windows 7

    Выделить (затенение) сюжетный фон в определенном временном диапазоне

    Значки разного размера на рабочем столе?

    Как я могу запускать системные команды Perl в фоновом режиме?

    Извлечение шаблонов начального экрана Windows 8

    Как передавать аудио / видео файлы, такие как MP3, MP4, AVI и т. Д. С помощью сервлета

    Найти ближайшее значение в векторе с бинарным поиском

    Обновление до Chrome 36, черный экран, отсутствие адресной строки, невозможно удалить

    Что находится в LibreOffice Вычислить эквивалент Excel «Специальная вставка»> «Значение»?

    Невозможно использовать запрос LIKE в JDBC PreparedStatement?

    Как вы вычисляете день года на определенную дату в Objective-C?

    Можно ли программно отключить iPhone?

    Давайте будем гением компьютера.