在聚合和汇总其他列时保留特定列数据

时间:2015-08-31 03:03:39

标签: r

我是R的新手,并使用中型零售店的交易数据来实践。我想创建一个数据框,其中包含每个客户在不同类别产品中的购买百分比,以及他们总购买量的总和。这样,我们就可以向给定类别中具有明显偏好的人发送营销电子邮件,但不包括购买次数少于5次的人。

样本数据(实际上近100个类别除外,大约有250,000行):

+-------------+-------------+--------------------+------+------+------+
| Transaction | Customer_ID | Email              | Cat1 | Cat2 | Cat3 |
+-------------+-------------+--------------------+------+------+------+
| 55          | 1           | email@address.com  | 1    | 0    | 0    |
| 55          | 1           | email@address.com  | 1    | 0    | 0    |
| 56          | 2           | email2@address.com | 0    | 0    | 2    |
| 57          | 3           | email3@address.com | 3    | 0    | 0    |
+-------------+-------------+--------------------+------+------+------+

步骤1:要按客户ID汇总,我使用了以下代码:

segmented <- aggregate(df[4:6], list(Customer_ID=orders$Customer_ID), FUN = sum)    

步骤2:为了使这些汇总的数字成为百分比,我使用了以下代码:

segmented_percentage <- cbind(id = segmented[, 1], segmented[, -1]/rowSums(segmented[, -1])*100)

但是,我在步骤1中丢失了电子邮件地址,当我尝试将数据框与下面的数据框合并时,它从未完成处理(我等了几个小时)。

merge(segmented_percentage, df)

简而言之:我如何将这么多部分重新组合在一起,以获得具有已证明的偏好和总购买量的电子邮件?

(非常感谢Stack Overflow的所有其他答案。我上面所取得的完全是谷歌搜索的结果,并在这里找到了好的答案。)

1 个答案:

答案 0 :(得分:1)

我们也可以使用Email作为分组变量来获取“电子邮件”列。在&#39;细分&#39;中,假设特定的&#39; Customer_ID&#39;有相同的电子邮件&#39;

segmented <- aggregate(.~Customer_ID+Email, df1[-1], FUN=sum)

如果我们要在原始数据集中创建列,请使用mutate中的library(dplyr)

library(dplyr)
df2 <- df1 %>% 
         group_by(Customer_ID) %>% 
         mutate_each(funs(sum= sum(., na.rm=TRUE)), starts_with('Cat'))

我们从“Cat&#39;”中获得了百分比。列并指定输出以用百分比替换列。

ind <- grep('Cat', names(df2))
df2[ind] <- df2[ind]/rowSums(df2[ind])*100

或者我们可以将prop.tablemargin=1

一起使用
df2[ind] <-  100*prop.table(as.matrix(df2[ind] ), 1)

我们也可以使用data.table执行此操作。我们转换了&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df1)),将我们要更改的列的class更改为numericlapply(.SD, as.numeric))。可以在.SDcols中指定要选择的列,我们可以将输出分配(:=)回到具有数字列索引的列。按照&#39; Customer_ID&#39;进行分组,我们使用lapply循环显示第4:6列并获取sum。我们使用Reduce+进行lapply输出的元素和(与rowSums相似),将sum除以{Reduce 1}} Map内的输出,并将输出分配给4:6列。

library(data.table)
 setDT(df1)[, (4:6) := lapply(.SD, as.numeric), .SDcols=4:6][,
   (4:6) := {tmp <- lapply(.SD, sum, na.rm=TRUE)
             Map(f1, tmp, Reduce(`+`, tmp))}, by = Customer_ID, .SDcols=4:6]

数据

df1 <- structure(list(Transaction = c(55L, 55L, 56L, 57L), 
Customer_ID = c(1L, 
1L, 2L, 3L), Email = c("email@address.com", "email@address.com", 
"email2@address.com", "email3@address.com"), Cat1 = c(1L, 1L, 
0L, 3L), Cat2 = c(0L, 0L, 0L, 0L), Cat3 = c(0L, 0L, 2L, 0L)),
.Names = c("Transaction", 
"Customer_ID", "Email", "Cat1", "Cat2", "Cat3"), 
 class = "data.frame", row.names = c(NA,  -4L))
相关问题