每天汇总 data.frame
Aggregate data.frame for each day
我有一个data.frame dat
关于二手车销售商的汽车销售(Buy=0
在数据框中)和购买(Buy=1
在数据框中) .
Date Buy Price
29-06-2015 1 5000
29-06-2015 0 8000
29-06-2015 1 10000
30-06-2015 0 3500
30-06-2015 0 12000
... ... ...
我需要的是一个新的汇总 data.frame,它可以提供每天的买入和卖出数量以及当天所有买入和卖出的总价:
Date Buys Sells Price_Buys Price_Sells
29-06-2015 2 1 15000 8000
30-06-2015 0 2 0 15500
... ... ...
我尝试使用 aggregate(dat$Buy, by=list(Date=dat$Date, FUN=sum))
。但是,我还在为如何汇总销售量而苦恼。
这可以在 dplyr
中非常干净地完成,使用 group_by
按日期分组,然后使用 summarize
:
进行总结
library(dplyr)
(out <- dat %>%
group_by(Date) %>%
summarize(Buys=sum(Buy == 1), Sells=sum(Buy == 0),
Price_Buys=sum(Price[Buy == 1]), Price_Sells=sum(Price[Buy == 0])))
# Date Buys Sells Price_Buys Price_Sells
# (fctr) (int) (int) (int) (int)
# 1 29-06-2015 2 1 15000 8000
# 2 30-06-2015 0 2 0 15500
您现在可以像操作普通数据框一样操作此对象,例如像这样的东西:
out$newvar <- with(out, Sells*Price_Sells - Buys*Price_Buys)
out
# Source: local data frame [2 x 6]
# Date Buys Sells Price_Buys Price_Sells newvar
# (fctr) (int) (int) (int) (int) (int)
# 1 29-06-2015 2 1 15000 8000 -22000
# 2 30-06-2015 0 2 0 15500 31000
您可以使用库 dplyr
来执行此操作:
df %>% group_by(Date) %>% summarise(buys = sum(Buy == 1), sells = sum(Buy == 0), Price_Buys = sum(Price[Buy == 1]), Price_Sells = sum(Price[Buy == 0]))
Source: local data frame [2 x 5]
Date buys sells Price_Buys Price_Sells
(fctr) (int) (int) (int) (int)
1 29-06-2015 2 1 15000 8000
2 30-06-2015 0 2 0 15500
我自己会使用 dpylr
解决方案之一,但我认为它仍然值得注意,它也可以用 aggregate()
来完成,因为这是你开始的方式:
aggregate(cbind(Buys = Buy, Sells = !Buy,
Price_Buys = Price * Buy, Price_Sells = Price * !Buy) ~ Date,
data = dat, sum)
## Date Buys Sells Price_Buys Price_Sells
## 1 29-06-2015 2 1 15000 8000
## 2 30-06-2015 0 2 0 15500
这里的想法是让销售额达到 !Buy
。这会将 Buy
转换为逻辑值 (0 => TRUE
, 1 => FALSE
),然后对其应用 NOT 运算符 (!)。这样,0转化为1,1转化为0,计算价格的时候可以用同样的trick
此解决方案与其他解决方案的比较还应向您表明,dplyr
生成的代码可读性更高。
使用 data.table
V 1.9.6+,您现在可以为 fun
参数提供函数列表,因此我们可以使用 dcast
轻松解决此问题(无需手动指定任何条件)
library(data.table) # V1.9.6+
dcast(setDT(dat), Date ~ Buy , value.var = "Price", fun = list(length, sum))
# Date Price_length_0 Price_length_1 Price_sum_0 Price_sum_1
# 1: 29-06-2015 1 2 8000 15000
# 2: 30-06-2015 2 0 15500 0
或者如果我们想尝试 dplyr
,解决这个问题的可靠方法(再次,不指定任何条件)可能是
library(dplyr)
df %>%
group_by(Date, Buy) %>%
summarise_each(funs(sum, length), Price)
# Source: local data frame [3 x 4]
# Groups: Date [?]
#
# Date Buy sum length
# (fctr) (int) (int) (int)
# 1 29-06-2015 0 8000 1
# 2 29-06-2015 1 15000 2
# 3 30-06-2015 0 15500 2
我有一个data.frame dat
关于二手车销售商的汽车销售(Buy=0
在数据框中)和购买(Buy=1
在数据框中) .
Date Buy Price
29-06-2015 1 5000
29-06-2015 0 8000
29-06-2015 1 10000
30-06-2015 0 3500
30-06-2015 0 12000
... ... ...
我需要的是一个新的汇总 data.frame,它可以提供每天的买入和卖出数量以及当天所有买入和卖出的总价:
Date Buys Sells Price_Buys Price_Sells
29-06-2015 2 1 15000 8000
30-06-2015 0 2 0 15500
... ... ...
我尝试使用 aggregate(dat$Buy, by=list(Date=dat$Date, FUN=sum))
。但是,我还在为如何汇总销售量而苦恼。
这可以在 dplyr
中非常干净地完成,使用 group_by
按日期分组,然后使用 summarize
:
library(dplyr)
(out <- dat %>%
group_by(Date) %>%
summarize(Buys=sum(Buy == 1), Sells=sum(Buy == 0),
Price_Buys=sum(Price[Buy == 1]), Price_Sells=sum(Price[Buy == 0])))
# Date Buys Sells Price_Buys Price_Sells
# (fctr) (int) (int) (int) (int)
# 1 29-06-2015 2 1 15000 8000
# 2 30-06-2015 0 2 0 15500
您现在可以像操作普通数据框一样操作此对象,例如像这样的东西:
out$newvar <- with(out, Sells*Price_Sells - Buys*Price_Buys)
out
# Source: local data frame [2 x 6]
# Date Buys Sells Price_Buys Price_Sells newvar
# (fctr) (int) (int) (int) (int) (int)
# 1 29-06-2015 2 1 15000 8000 -22000
# 2 30-06-2015 0 2 0 15500 31000
您可以使用库 dplyr
来执行此操作:
df %>% group_by(Date) %>% summarise(buys = sum(Buy == 1), sells = sum(Buy == 0), Price_Buys = sum(Price[Buy == 1]), Price_Sells = sum(Price[Buy == 0]))
Source: local data frame [2 x 5]
Date buys sells Price_Buys Price_Sells
(fctr) (int) (int) (int) (int)
1 29-06-2015 2 1 15000 8000
2 30-06-2015 0 2 0 15500
我自己会使用 dpylr
解决方案之一,但我认为它仍然值得注意,它也可以用 aggregate()
来完成,因为这是你开始的方式:
aggregate(cbind(Buys = Buy, Sells = !Buy,
Price_Buys = Price * Buy, Price_Sells = Price * !Buy) ~ Date,
data = dat, sum)
## Date Buys Sells Price_Buys Price_Sells
## 1 29-06-2015 2 1 15000 8000
## 2 30-06-2015 0 2 0 15500
这里的想法是让销售额达到 !Buy
。这会将 Buy
转换为逻辑值 (0 => TRUE
, 1 => FALSE
),然后对其应用 NOT 运算符 (!)。这样,0转化为1,1转化为0,计算价格的时候可以用同样的trick
此解决方案与其他解决方案的比较还应向您表明,dplyr
生成的代码可读性更高。
使用 data.table
V 1.9.6+,您现在可以为 fun
参数提供函数列表,因此我们可以使用 dcast
轻松解决此问题(无需手动指定任何条件)
library(data.table) # V1.9.6+
dcast(setDT(dat), Date ~ Buy , value.var = "Price", fun = list(length, sum))
# Date Price_length_0 Price_length_1 Price_sum_0 Price_sum_1
# 1: 29-06-2015 1 2 8000 15000
# 2: 30-06-2015 2 0 15500 0
或者如果我们想尝试 dplyr
,解决这个问题的可靠方法(再次,不指定任何条件)可能是
library(dplyr)
df %>%
group_by(Date, Buy) %>%
summarise_each(funs(sum, length), Price)
# Source: local data frame [3 x 4]
# Groups: Date [?]
#
# Date Buy sum length
# (fctr) (int) (int) (int)
# 1 29-06-2015 0 8000 1
# 2 29-06-2015 1 15000 2
# 3 30-06-2015 0 15500 2