-3

我有一个垂直排列(堆叠)的合并时间序列data.frame,如下所示:

date    item    qty_sold
day_1   orange  0
day_2   orange  0
day_3   orange  0
day_4   orange  0
day_5   orange  5
day_6   orange  0
day_7   orange  8
day_8   orange  0
day_1   hammer  0
day_2   hammer  0
day_3   hammer  3
day_4   hammer  0
day_5   hammer  70
day_6   hammer  70
day_7   hammer  0
Day_8   hammer  80

在每个“项目的”子系列/子组中,我需要识别并删除*在观察到第一个正 qty_sold 的那一天之前的所有观察结果*。例如,对于“橙色”系列,这意味着淘汰第 1 天到第 4 天,而对于“锤子”系列,这意味着淘汰前 2 天。


(如果上面的解释不清楚):从数据集中的每个子系列中,我需要删除从 date = Day_1 到 date = Day_k 的所有天,这样对于间隔 1 中的每一天...... k qty_sold = 0,并保留 date = Day_k+1 qty_sold >= 0 的所有行)

任何人都可以就如何解决这个问题提出一个想法吗?实际数据集包含大约一百万行。除了 R 之外,我也欢迎使用 SAS 来完成此任务的建议。

4

2 回答 2

3

我完全同意@joran 的观点。即使这个问题没有显示任何研究工作,我也会在这里给出一个(n)(R)答案。将来,请向我们展示您尝试过的代码。

对于您的问题,第一步是使用一个基本函数或一个不错的包来帮助splitdata.frame进行分组,apply无论您想应用于每个拆分组和combine结果的任何函数(通常称为split-apply-combine策略)。那里有几个不错的(外部)包,即plyrdata.table. 虽然,我更喜欢类似的操作,因为它通常data.tabledata.frame快得多。

因此,首先我们将您转换data.framedata.table. 如果你没有安装这个包,那么你可以通过install.packages("data.table").

require(data.table) # load package
dt <- data.table(df) # convert data.frame to data.table

现在,要将 a分成组data.table,我们可以使用. 我们的函数将是,因为这只会在第一个连续的零和之后的非零中为您提供 0(如果您的数据中没有负值,我在这里假设)。然后,自动组合结果。所以,让我们这样做:bydata.tableapplycummax

dt[, .SD[cummax(qty_sold) > 0], by = item]

      item  date qty_sold
 1: orange day_5        5
 2: orange day_6        0
 3: orange day_7        8
 4: orange day_8        0
 5: hammer day_3        3
 6: hammer day_4        0
 7: hammer day_5       70
 8: hammer day_6       70
 9: hammer day_7        0
10: hammer Day_8       80

总结一下:

require(data.table)
dt <- data.table(df)
dt[, .SD[cummax(qty_sold)>0], by = item]

关于语法的更多解释。我们先考虑一下by = item。这是内部split为您提供数据的部分item(即首先考虑整个data.tablefor item= orange,然后是 for 的部分item = hammer等)。

中间部分.SD[cummax(qty_sold) > 0]是魔法发生的地方——apply等效的功能。在这里,.SD只是拆分部分(对应于item一次取一个。要更清楚地看到.SD每次都有什么,请执行以下操作:dt[, print(.SD), by = item].

这将基本上删除在开始时具有连续 0 的行并保留其他所有内容(只要没有负值,就可以保证解决方案)。

于 2013-07-06T22:50:15.753 回答
2

SAS 方法类似于:在保留变量中跟踪您是否已经遇到项目的正值。如果不是,则不输出。如果是,请在用于跟踪它的变量中记下它。在项目的最后一行之后,重置您的跟踪变量。例如:(必要时排序)

data RESULT (drop=found_first_positive);
    set DATASET;
    by item date;
    retain found_first_positive 0;
    if quantity>0 then found_first_positive=1;
    if found_first_positive;
    if last.item then found_first_positive=0;
run;
于 2013-07-06T23:07:54.400 回答