如何用dplyr实现按ProductCode右连接并将行转列?
使用dplyr和tidyr实现按ProductCode关联并行列转换的需求
当然可以用dplyr搭配tidyr来完成这个需求,而且代码比你提供的SQL写法更简洁直观,一起来看看具体怎么做:
首先,先确认我们的示例数据:
data1=data.frame(ProductCode=c(1,1,1,2,2,3),region=c("A","A","A","B","B","C")) data2=data.frame(ProductCode=c(1,1,1,2,2,3),Period=c("promo1","promo2","promo3","promo2","promo3","promo1"),promosales=c(15,12,7,18,20,2))
步骤说明
- 去重data1:因为data1里同一个
ProductCode对应重复的region值,先去重避免后续出现重复行。 - 将data2转为宽格式:把
Period列的不同值转成列名,同时给列名加上_sales后缀,没有对应销量的填充0。 - 关联两个表:按
ProductCode执行右连接(这里因为两个表的ProductCode完全匹配,用内连接也能得到相同结果)。
完整代码
首先加载需要的包:
library(dplyr) library(tidyr)
然后执行数据处理:
result <- data1 %>% # 对data1去重,保留每个ProductCode对应的唯一region distinct(ProductCode, region) %>% # 与转换后的data2执行右连接 right_join( data2 %>% # 将data2从长格式转宽格式 pivot_wider( id_cols = ProductCode, names_from = Period, values_from = promosales, names_prefix = "Promo", # 给列名加上_sales后缀 names_transform = ~ paste0(., "_sales"), # 缺失的销量填充0 values_fill = 0 ), by = "ProductCode" )
查看最终结果:
print(result) # ProductCode region Promo1_sales Promo2_sales Promo3_sales # 1 1 A 15 12 7 # 2 2 B 0 18 20 # 3 3 C 2 0 0
补充说明
你提供的SQL代码里似乎有笔误(比如多个Promo1_sales前缀),而用dplyr+tidyr的方式不需要手动写大量case when语句,完全通过函数实现行列转换,代码可读性和维护性更高。
内容的提问来源于stack exchange,提问作者melik
相关产品推荐
相关产品推荐

