J'ai affaire à une trame de données contenant les données de niveau transaction. Il contient deux champs, bill_id
et product
.
Les données représentent les produits achetés au niveau de la facture et un bill_id
particulier est répété comme plusieurs fois le nombre de produits achetés dans cette facture. Par exemple, si 5 articles ont été achetés dans bill_id 12345, les données de cette facture seront comme suit:
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)
Mon objectif est de filtrer les données de toutes les factures contenant un certains produits.
Voici un exemple de la façon dont j'effectue cette tâche actuellement:
bill_id product 12345 A 12345 B 12345 C 12345 D 12345 E
Cela conduit à la création d'un vecteur intermédiaire de bill_ids ( factures_productA
) et un processus de filtrage en deux étapes (recherchez d'abord les identifiants des factures contenant le produit, puis recherchez toutes les transactions de ces factures).
Existe-t-il un moyen plus efficace de effectuer cette tâche?
3 Réponses :
Vous pouvez filtrer
le bill_id
en le sous-définissant directement
library(dplyr) dat_subset1 <- dat %>% filter(bill_id %in% unique(bill_id[product == "A"])) identical(dat_subset, dat_subset1) #[1] TRUE
Cela fonctionnerait également sans unique
mais il vaut mieux garder la liste courte.
Une autre variante:
library(dplyr) dat_subset2 <- semi_join(dat, filter(dat, product == "A") %>% select(bill_id)) > identical(dat_subset, dat_subset2) [1] TRUE
une approche data.table:
préparation
# 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
code réel
dat[ bill_id %in% dat[ product == "A",][[1]], ]
sortie
library(data.table) setDT(dat)