2
votes

Filtrage des données au niveau des transactions

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?


0 commentaires

3 Réponses :


0
votes

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.


0 commentaires

0
votes

Une autre variante:

library(dplyr)
dat_subset2 <- semi_join(dat, filter(dat, product == "A") %>% select(bill_id))

> identical(dat_subset, dat_subset2) 
[1] TRUE


0 commentaires

0
votes

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)


0 commentaires