一种在数周内筛选数据框内容的快速方法

A quick way to screen a data frame contents over multiple weeks

我有一个数据框,其内容每周都会更改部分内容。

想象一下,我拥有一个汽车陈列室,每周之后我可能会卖掉一些汽车并收购其他汽车进行销售。我的任务是计算出每周汽车的平均销售时间。尽管在我的示例中,每周数据帧的长度相同,但情况不一定如此,因为我买的车可能比卖的车多,反之亦然。

考虑这 4 个数据框:

serial_no <- c('A1','B2','C3','D4','E5','F6')
brand <- c('Mercedes','BMW','Audi','Jaguar','Nissan','Volkswagen')
model <- c('S-class','5-series','Q8','XF','GT-R','Eos')
df.week1 <- data.frame(serial_no,brand,model)

serial_no2 <- c('B2','C3','D4','E5','F6','G7')
brand2 <- c('BMW','Audi','Jaguar','Nissan','Volkswagen','Mercedes')
model2 <- c('5-series','Q8','XF','GT-R','Eos','E-class')
df.week2 <- data.frame(serial_no2,brand2,model2)

serial_no3 <- c('B2','D4','E5','F6','G7','H8')
brand3 <- c('BMW','Jaguar','Nissan','Volkswagen','Mercedes','BMW')
model3 <- c('5-series','XF','GT-R','Eos','E-class','5-series')
df.week3 <- data.frame(serial_no3,brand3,model3)

serial_no4 <- c('D4','F6','G7','I9','J10','K11')
brand4 <- c('Jaguar','Volkswagen','Mercedes','BMW','Toyota','Lexus')
model4 <- c('XF','Eos','E-class','7-series','Corolla','RC')
df.week4 <- data.frame(serial_no4,brand4,model4)

#to tidy up

library(plyr)
df.week2 <- rename(df.week2,c('serial_no2' = 'serial_no','brand2'='brand','model2'='model'))
df.week3 <- rename(df.week3,c('serial_no3' = 'serial_no','brand3'='brand','model3'='model'))
df.week4 <- rename(df.week4,c('serial_no4' = 'serial_no','brand4'='brand','model4'='model'))

现在我可以很简单地告诉我上周卖出了哪些车,例如:

library(dplyr)
in3not4 <- anti_join(df.week3,df.week4,by='serial_no')

但是,我的任务的第二部分是首先找到他们何时进入陈列室。显然,可以通过使用多种 anti_join 技术来实现这一目标,但是要分析很多周和数千行,这很快就会成为一项令人难以置信的任务。

那么我的问题是,是否有更简单的方法来执行此任务?我需要找出答案:

A) 售出的汽车首次出现在展厅时

B) 给定一周内售出的所有汽车的平均销售时间是多少(注意我的 df 'in3not4' 显示在第 3 周开始和第 4 周开始之间售出的所有汽车)

我不得不认为有一个简单的工具可以完成这项任务。感谢任何帮助。

我不确定我是否清楚地了解您希望输出的样子。但这是使用 data.table v1.9.5 的尝试 - 安装说明 here:

require(data.table) # v1.9.5+
m.dt = rbindlist(list(df.week1, df.week2, df.week3, df.week4), idcol = "week")
max_week = max(m.dt$week)
ans = m.dt[, .(week_in  = week[1L], 
               week_out = ifelse(max_week == week[.N], NA_integer_, week[.N])), 
          by=.(serial_no, brand, model)]
#     serial_no      brand    model week_in week_out
#  1:        A1   Mercedes  S-class       1        1
#  2:        B2        BMW 5-series       1        3
#  3:        C3       Audi       Q8       1        2
#  4:        D4     Jaguar       XF       1       NA
#  5:        E5     Nissan     GT-R       1        3
#  6:        F6 Volkswagen      Eos       1       NA
#  7:        G7   Mercedes  E-class       2       NA
#  8:        H8        BMW 5-series       3        3
#  9:        I9        BMW 7-series       4       NA
# 10:       J10     Toyota  Corolla       4       NA
# 11:       K11      Lexus       RC       4       NA

思路应该很清楚(假设我已经正确理解了任务)。我会把剩下的留给你,以你想要的形式得到它..