将时间序列事务数据转换为 R 中所有产品的出现计数表

Converting time series transaction data into an occurrence count table of all products in R

提问人:Cindy Burker 提问时间:9/20/2022 更新时间:9/20/2022 访问量:151

问:

我有 500 万行 + 行每日交易数据,列格式为(年、月、月、日、时、购买的产品): 我创建了这个数据框作为示例(请注意,原始数据没有像我在这个例子中给出的那样排序,并且日期范围跨度为 4 年。

enter image description here

all_product_names = c("a","b","c","d","e","f","g","h","i")
my_table <- data.frame(year = c(2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022),
           month = c(rep(4,12)),
           day = c(rep(3,12)),
           hour = c(0,0,0,0,0,0,1,1,1,1,2,2),
           product_name = c("a","b","c","a","c","c","d","f","a","b","c","f") )

我想要的输出是一个表格,在给定的时间实例(年-月-日-小时的特定组合)下,所有产品购买的计数都作为列扩展到表格中。“all_product_names”变量为您提供所有现有产品的列表。请注意,并非每次实例都购买了所有产品时,对于这些实例,该产品的“计数表”值必须为零。这是我试图让我的输出分组看起来像什么:

enter image description here

使用 sqldf,我尝试按产品分组,以便获得每个实例的product_name计数,但是它不计入每个实例不存在的产品。我还需要将行格式转换为列,如上面的解决方案表示例所示。

xx <-sqldf('SELECT year,month,day,hour,product_name,COUNT(product_name) FROM my_table GROUP BY product_name,hour,day,month,year
      ORDER BY product_name ASC')

另外,请注意,我不必使用 sqldf 库。感谢您抽出宝贵时间接受采访!

R Data.Table 数据操作 SQLDF

评论

0赞 Jon Spring 9/20/2022
您能否澄清一下是否希望输出包含源数据中可能不存在(在这种情况下不存在)的 g/h/i 等列?

答:

1赞 Jon Spring 9/20/2022 #1
library(tidyverse)
my_table %>%
  count(year, month, day, hour, product_name) %>%
  pivot_wider(names_from = product_name, values_from = n, values_fill = 0)

评论

1赞 Cindy Burker 9/20/2022
我不敢相信解决方案如此简短和简单。非常感谢您抽出宝贵时间接受采访!
0赞 B. Christian Kamgang 9/20/2022
如果我说结果与预期输出不同,我错了吗?透视后缺少某些列(列 G 到 I)。
0赞 Merijn van Tilborg 9/20/2022 #2
library(data.table)

setDT(my_table) # if not yet a data.table

results <- dcast(my_table, year + month + day + hour ~ product_name, fun.aggregate = length)

results[, setdiff(all_product_names, my_table$product_name) := 0L]
setcolorder(results, c(names(my_table)[1:4], all_product_names))


results
#    year month day hour a b c d e f g h i
# 1: 2022     4   3    0 2 1 3 0 0 0 0 0 0
# 2: 2022     4   3    1 1 1 0 1 0 1 0 0 0
# 3: 2022     4   3    2 0 0 1 0 0 1 0 0 0

评论

1赞 B. Christian Kamgang 9/20/2022
因为 ,没有必要指定,因为对于不存在的组合,它无论如何都是 0。另外,我认为结果与预期输出略有不同。您可以考虑在当前结果中添加类似内容;但如果我错了,请告诉我。fun.aggregate=lengthfill=0result[, setdiff(all_product_names, my_table$product_name) := 0L]
1赞 Merijn van Tilborg 9/20/2022
有效的建议,我添加了代码以获得完整的 OP 所需的结果