ddply резюмировать по нескольким переменным

Я вижу, что ddply прекрасно суммирует и группирует по переменным. Я хочу, чтобы ddply просканировал очень большой фрейм данных только один раз и предоставил мне количество (длину) для более чем одной переменной. Как это может быть сделано? Например:

inc <- c('inc123', 'inc332', 'inc231', 'inc492', 'inc872', 'inc983')
hw <- c('ss23', 'ss43', 'ss98', 'ss98', 'ss23', 'ss23')
app <- c('lkl', 'dsd', 'lkl', 'jhj', 'lkl', 'dsd')
srvc <- c('rr', 'oo', 'rr', 'qq', 'qq', 'pp')

df <- data.frame(inc, hw, app, srvc)
ddply(df, .(hw), summarise, count = length(inc))

Вышеупомянутое даст мне количество уникальных hw. Если я сделаю

ddply(df, .(hw, app, srvc), summarise, count = length(inc))

моя цель потеряна, потому что ddply берет каждую "уникальную" комбинацию hw, app, srvc и считает их.

Есть ли способ получить количество всех трех переменных за один раз? Ожидайте, что результирующий df будет примерно таким: (может иметь различное количество строк).

    hw count
1 ss23     3
2 ss43     1
3 ss98     2

    app count
1   dsd     2
2   jhj     1
3 linux     1
4   lkl     2

  srvc count
1   oo     1
2   pp     1
3   qq     2
4   rr     2

person user1717931    schedule 17.07.2013    source источник
comment
это кажется несовместимым со стратегией plyr «разделить и применить»: вы просите разбить data.frame на 11 групп, которые не пересекаются.   -  person baptiste    schedule 18.07.2013
comment
Теперь я это понимаю. использование «unique» также требует, чтобы я запускал его один раз для каждой переменной.   -  person user1717931    schedule 18.07.2013


Ответы (2)


Я не знаю, что plyr делает внутри, но data.table будет использовать только столбцы, которые есть в самом выражении, эффективно сканируя данные только один раз (столбец за столбцом):

library(data.table)
dt = data.table(df)

lapply(c('hw', 'app', 'srvc'), function(name) dt[, .N, by = name])
person eddi    schedule 17.07.2013
comment
Большое спасибо Эдди и Дикоа. Мне нравятся оба их решения. Однако Data.Table работает быстрее. - person user1717931; 18.07.2013

Вы можете использовать plyr::count для этого

require(plyr)
llply(c("hw", "app", "srvc"), function(col) count(df, vars = col))
## [[1]]
##     hw freq
## 1 ss23    3
## 2 ss43    1
## 3 ss98    2

## [[2]]
##   app freq
## 1 dsd    2
## 2 jhj    1
## 3 lkl    3

## [[3]]
##   srvc freq
## 1   oo    1
## 2   pp    1
## 3   qq    2
## 4   rr    2
person dickoa    schedule 17.07.2013