每天汇总数据框

5

我有一个关于二手车销售商的数据框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 
...          ...  ...

我需要的是一个新的、合并的数据框,它可以给我每天买入和卖出的数量,以及当天所有买入和卖出的总价格:
  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))。然而,我仍在努力想办法如何聚合销售额。

1
我在您的原始数据集中没有看到任何关于销售的信息。 - Stibu
3
我认为“买入”一栏中的零表示“卖出”,而一表示“买入”。 - zx8754
4个回答

6

可以在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

非常感谢!这正是我一直在寻找的。还有一个问题:如何处理新本地数据框的列,例如计算每天收入的新列(销售量 x 销售价格 - 购买量 x 购买价格)? - jeffrey
@jeffrey,我已更新答案以显示如何添加新变量。 - josliber

4

使用 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

3

我个人会使用dplyr中的一种解决方案,但是我认为值得注意的是,也可以使用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。在计算价格时也可以使用相同的技巧。
与其他解决方案的比较也应该向您展示,dplyr生成的代码更易读。

3
您可以使用库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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接