在R Studio中重构客户产品数据的技术求助
在R Studio中重构客户产品数据的技术求助
嗨,作为R新手遇到数据重构问题太正常了,别慌!我来帮你一步步搞定这个需求~
先明确你的核心目标:把原始的长格式客户购买数据,转换成宽格式——每个客户的产品按购买数量重复后,依次列成Prod1、Prod2这类字段,对吧?
首先先把你的原始数据整理成更易读的代码形式:
sample <- data.frame( num = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), CustomerID = c(1, 2, 2, 3, 3, 4, 4, 4, 4, 5), product = c("Eggs", "Bread", "Coke", "Coke", "Eggs", "Apples", "Bread", "Cookies", "Coke", "Milk"), quantity = c(1, 1, 3, 2, 2, 1, 2, 1, 3, 1) )
下面给你两种实现方法,一种用基础R,一种用更适合新手的tidyverse工具:
方法一:基础R实现
步骤1:按购买数量扩展产品行
首先我们需要把每个产品根据quantity的值重复对应次数,比如购买3份Coke就生成3行Coke数据:
expanded_data <- data.frame( CustomerID = rep(sample$CustomerID, sample$quantity), product = rep(sample$product, sample$quantity) )
步骤2:给每个客户的产品添加序号
reshape()函数需要一个区分同一客户下不同产品的标识,所以我们给每个客户的产品按顺序编号:
expanded_data$prod_num <- ave(expanded_data$product, expanded_data$CustomerID, FUN = seq_along)
步骤3:转成宽格式
最后用reshape()完成格式转换,再调整列名:
wide_data <- reshape( expanded_data, idvar = "CustomerID", # 分组依据:客户ID timevar = "prod_num", # 区分同客户下不同产品的字段 direction = "wide", # 转换方向:宽格式 v.names = "product" # 要转换的目标字段 ) # 把列名从product.1改成Prod1,更符合你的需求 colnames(wide_data) <- gsub("product\\.", "Prod", colnames(wide_data))
方法二:tidyverse工具(推荐新手,代码更直观)
如果你愿意尝试tidyverse这套数据处理工具,代码会更简洁易读。先安装并加载包:
install.packages("tidyverse") library(tidyverse)
然后用链式操作一步完成:
wide_data_tidy <- sample %>% # 按购买数量扩展数据行 uncount(quantity) %>% # 给每个客户的产品按顺序生成Prod1/Prod2...的列名标识 group_by(CustomerID) %>% mutate(prod_num = paste0("Prod", row_number())) %>% ungroup() %>% # 转换为宽格式 pivot_wider(names_from = prod_num, values_from = product)
最终结果验证
运行后你会得到符合预期的结果,比如:
CustomerID Prod1 Prod2 Prod3 Prod4 Prod5 Prod6 Prod7 1 1 Eggs <NA> <NA> <NA> <NA> <NA> <NA> 2 2 Bread Coke Coke Coke <NA> <NA> <NA> 3 3 Coke Coke Eggs Eggs <NA> <NA> <NA> 4 4 Apples Bread Bread Cookies Coke Coke Coke 5 5 Milk <NA> <NA> <NA> <NA> <NA> <NA>
之前你用reshape()没成功,大概率是因为没给同客户的产品添加序号标识——reshape()需要这个标识来区分同一客户下的不同产品行,补上这一步就没问题啦!
备注:内容来源于stack exchange,提问作者Helpseeker
相关产品推荐
相关产品推荐

