如何在R语言中筛选每个客户首单的全部Product_ID?
保留每个客户首单所有商品行的解决方案
原始数据集
首先创建示例数据集:
df <- data.frame(customerID=c(123,123,456,123,789,789,789,123,789), orderID=c(1,1,2,3,4,4,4,5,6), Product_ID=c('A','B','C','C','D','D','E','C','D'))
对应的原始表格:
| customerID | orderID | Product_ID |
|---|---|---|
| 123 | 1 | A |
| 123 | 1 | B |
| 456 | 2 | C |
| 123 | 3 | C |
| 789 | 4 | D |
| 789 | 4 | D |
| 789 | 4 | E |
| 123 | 5 | C |
| 789 | 6 | D |
需求说明
仅保留每个客户首单对应的所有Product_ID行,期望结果如下:
| customerID | orderID | Product_ID |
|---|---|---|
| 123 | 1 | A |
| 123 | 1 | B |
| 456 | 2 | C |
| 789 | 4 | D |
| 789 | 4 | D |
| 789 | 4 | E |
问题分析
原尝试代码仅返回每个客户的第一行数据,无法保留首单内的所有商品行:
first_order <- df %>% group_by(customerid) %>% filter(row_number()==1)
原因是row_number()==1仅筛选分组内的第一行,而非所有属于首单的行。
解决方案
方法1:分组获取首单ID后过滤
先提取每个客户的首单orderID,再关联原数据集筛选对应行:
library(dplyr) first_order_ids <- df %>% group_by(customerID) %>% summarise(first_order = min(orderID)) result <- df %>% inner_join(first_order_ids, by = "customerID") %>% filter(orderID == first_order) %>% select(-first_order)
方法2:分组后直接匹配最小orderID
在分组内直接筛选orderID等于该组最小值的所有行:
result <- df %>% group_by(customerID) %>% filter(orderID == min(orderID)) %>% ungroup()
方法3:使用slice_min简洁实现
slice_min的with_ties = TRUE参数会保留所有与最小orderID匹配的行:
result <- df %>% group_by(customerID) %>% slice_min(order_by = orderID, with_ties = TRUE) %>% ungroup()
内容的提问来源于stack exchange,提问作者T. Troglodyte
相关产品推荐
相关产品推荐

