计算频率并添加总和

Count frequencies and add a total sum

我有一个很大的 data.frame 包含这些值:

ID_Path    Conversion    Lead    Path    Week
32342      A25177        1       JEFD    2015-25
32528      A25177        1       EUFD    2015-25
25485      A3            1       DTFE    2015-25
32528      Null          0       DDFE    2015-25
23452      A25177        1       JDDD    2015-26
54454      A25177        1       FDFF    2015-27
56848      A2323         1       HDG     2015-27

我希望能够创建一个显示 table 的频率 table,如下所示:

Week       Total    A25177    A3    A2323
2015-25    3        2         1     0
2015-26    1        1         0     0
2015-27    2        1         0     1

每个唯一的 Conversion 都有一个列,并且 Conversion 为 Null 的所有时间与 Lead 为 0 的时间相同。 在此示例中,有 3 次唯一转化,有时有 1 次,有时有 5 次或更多。所以不应该仅限于3.

我创建了一个新的 DF,其中仅包含 Conversion 而不是 Null 我试过使用 data.table 和这个代码:

DF[,list(Week=Week,by=Conversion]

运气不好。

我试过使用 plyr 和这个代码:

ddply(DF,~Conversion,summarise,week=week)

运气不好。

我建议删除不必要的级别以免弄乱输出,然后 运行 一个简单的 tableaddmargins 组合

DF <- droplevels(DF[DF$Conversion != "Null",])

addmargins(table(DF[c("Week", "Conversion")]), 2)
# Conversion
# Week      A2323 A25177 A3 Sum
#   2015-25     0      2  1   3
#   2015-26     0      1  0   1
#   2015-27     1      1  0   2

或者,您可以在指定 margins 参数时对 reshape2 执行相同的操作

library(reshape2)
dcast(DF, Week ~ Conversion, value.var = "Conversion", length, margins = "Conversion")
#      Week A2323 A25177 A3 (all)
# 1 2015-25     0      2  1     3
# 2 2015-26     0      1  0     1
# 3 2015-27     1      1  0     2

使用 dplyr 和 tidyr 的替代解决方案:

library(tidyr)
library(dplyr)

dt = data.frame(Conversion = c("A1","Null","A1","A3"),
                Lead = c(1,0,1,1),
                Week = c("2015-25","2015-25","2015-25","2015-26"))

dt %>% 
  filter(Conversion != "Null") %>%
  group_by(Week, Conversion) %>% 
  summarise(Lead = sum(Lead)) %>%
  ungroup() %>% 
  spread(Conversion,Lead,fill=0) %>%
  group_by(Week) %>%
  do(data.frame(.,
                Total = sum(.[,-1]))) %>%
  ungroup()

#     Week A1 A3 Total
# 1 2015-25  2  0     2
# 2 2015-26  0  1     1