我正在处理一个包含事务级别数据的数据帧。它包含两个字段bill_id
和product
。
数据代表按帐单级别购买的产品,并且特定的bill_id
的重复次数与该帐单中购买的产品数量相同。例如,如果在bill_id 12345中购买了5件商品,则该账单的数据将如下所示:
bill_id product
12345 A
12345 B
12345 C
12345 D
12345 E
我的目标是过滤出包含某种产品的所有账单数据。
以下是我当前如何执行此任务的一个示例:
library(dplyr)
set.seed(1)
# Sample data
dat <- data.frame(bill_id = sample(1:500, size = 1000, replace = TRUE),
product = sample(LETTERS, size = 1000, replace =
TRUE),
stringsAsFactors = FALSE) %>%
arrange(bill_id, product)
# vector of bill_ids of product A
bills_productA <- dat %>%
filter(product == "A") %>%
pull(bill_id) %>%
unique()
# data for bill_ids in vector bills_productA
dat_subset <- dat %>%
filter(bill_id %in% bills_productA)
这导致创建bill_ids(bills_productA
)的中间向量和两步筛选过程(首先找到包含产品的票据id,然后找到这些票据的所有交易)。
有没有更有效的方法来执行此任务?
答案 0 :(得分:0)
您可以通过直接子设置filter
bill_id
library(dplyr)
dat_subset1 <- dat %>% filter(bill_id %in% unique(bill_id[product == "A"]))
identical(dat_subset, dat_subset1)
#[1] TRUE
这也可以在没有unique
的情况下工作,但最好使列表简短。
答案 1 :(得分:0)
另一种变化:
library(dplyr)
dat_subset2 <- semi_join(dat, filter(dat, product == "A") %>% select(bill_id))
> identical(dat_subset, dat_subset2)
[1] TRUE
答案 2 :(得分:0)
data.table方法:
准备工作
library(data.table)
setDT(dat)
实际代码
dat[ bill_id %in% dat[ product == "A",][[1]], ]
输出
# bill_id product
# 1: 14 A
# 2: 14 I
# 3: 19 A
# 4: 19 W
# 5: 22 A
# ---
# 130: 478 A
# 131: 478 V
# 132: 478 Z
# 133: 494 A
# 134: 494 J