Сумма по значению отдельного столбца в R
у меня очень большой фрейм данных в R и я хотел бы суммировать два столбца для каждого отдельного значения в других столбцах, например, скажем, у нас были данные фрейма данных транзакций в различных магазинах в течение дня следующим образом
shop <- data.frame('shop_id' = c(1, 1, 1, 2, 3, 3),
'shop_name' = c('Shop A', 'Shop A', 'Shop A', 'Shop B', 'Shop C', 'Shop C'),
'city' = c('London', 'London', 'London', 'Cardiff', 'Dublin', 'Dublin'),
'sale' = c(12, 5, 9, 15, 10, 18),
'profit' = c(3, 1, 3, 6, 5, 9))
что:
shop_id shop_name city sale profit
1 Shop A London 12 3
1 Shop A London 5 1
1 Shop A London 9 3
2 Shop B Cardiff 15 6
3 Shop C Dublin 10 5
3 Shop C Dublin 18 9
и я хотел бы суммировать продажу и прибыль для каждого магазина, чтобы дать:
shop_id shop_name city sale profit
1 Shop A London 26 7
2 Shop B Cardiff 15 6
3 Shop C Dublin 28 14
в настоящее время я использую следующий код для этого:
shop_day <-ddply(shop, "shop_id", transform, sale=sum(sale), profit=sum(profit))
shop_day <- subset(shop_day, !duplicated(shop_id))
, которая работает абсолютно нормально, но, как я сказал мой фрейм данных большой (140,000 строк, 37 столбцов и почти 100,000 уникальных строк, которые я хочу суммировать), и мой код занимает годы, а затем в конечном итоге говорит, что у него закончилась память.
кто-нибудь знает наиболее эффективный способ сделать это.
спасибо заранее!
2 ответов
** обязательная таблица данных ответ **
> library(data.table)
data.table 1.8.0 For help type: help("data.table")
> shop.dt <- data.table(shop)
> shop.dt[,list(sale=sum(sale), profit=sum(profit)), by='shop_id']
shop_id sale profit
[1,] 1 26 7
[2,] 2 15 6
[3,] 3 28 14
>
что звучит хорошо и хорошо, пока все не станет больше...
shop <- data.frame(shop_id = letters[1:10], profit=rnorm(1e7), sale=rnorm(1e7))
shop.dt <- data.table(shop)
> system.time(ddply(shop, .(shop_id), summarise, sale=sum(sale), profit=sum(profit)))
user system elapsed
4.156 1.324 5.514
> system.time(shop.dt[,list(sale=sum(sale), profit=sum(profit)), by='shop_id'])
user system elapsed
0.728 0.108 0.840
>
вы получаете дополнительные увеличения скорости, если вы создаете данные.таблица с ключом:
shop.dt <- data.table(shop, key='shop_id')
> system.time(shop.dt[,list(sale=sum(sale), profit=sum(profit)), by='shop_id'])
user system elapsed
0.252 0.084 0.336
>
вот как использовать базу R для ускорения таких операций:
idx <- split(1:nrow(shop), shop$shop_id)
a2 <- data.frame(shop_id=sapply(idx, function(i) shop$shop_id[i[1]]),
sale=sapply(idx, function(i) sum(shop$sale[i])),
profit=sapply(idx, function(i) sum(shop$profit[i])) )
время сокращается до 0.75 сек против 5.70 сек для версии ddply summarise в моей системе.