我是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的所有其他答案。我上面所取得的完全是谷歌搜索的结果,并在这里找到了好的答案。)
答案 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.table
与margin=1
df2[ind] <- 100*prop.table(as.matrix(df2[ind] ), 1)
我们也可以使用data.table
执行此操作。我们转换了&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df1)
),将我们要更改的列的class
更改为numeric
(lapply(.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))