【问题标题】:Filtering transaction level data过滤事务级别数据
【发布时间】:2019-03-07 08:11:02
【问题描述】:

我正在处理一个包含事务级别数据的数据框。它包含两个字段,bill_idproduct

数据代表按账单级别购买的产品,特定的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,然后查找这些票据的所有交易)。

有没有更有效的方法来执行这项任务?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

      您可以通过直接子集化 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 的情况下也可以工作,但最好保持列表简短。

      【讨论】:

        【解决方案3】:

        另一种变化:

        library(dplyr)
        dat_subset2 <- semi_join(dat, filter(dat, product == "A") %>% select(bill_id))
        
        > identical(dat_subset, dat_subset2) 
        [1] TRUE
        

        【讨论】:

          猜你喜欢
          • 2021-07-28
          • 1970-01-01
          • 2015-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-30
          相关资源
          最近更新 更多