R纵向数据 - 按多因素分组

时间:2012-09-07 13:32:03

标签: r time-series tabular

我仍在尝试创建详细的时间序列数据帧。我正在尝试获取多个数据点的月度数据,然后按多个因素进行分组。我不确定这是否可行,因为我没有在文档,插图或SO中看到与此相关的示例。

以下是我尝试构建的示例数据:

clients <- 1:100
dates <- seq(as.Date("2012/1/1"), as.Date("2012/9/1"), "days")
categories <- LETTERS[1:5]
products <- data.frame(clientID = sample(clients, 10000, replace = TRUE), 
                       OrderDate = sample(dates, 10000, replace = TRUE), 
                       category = sample(categories, 10000, replace = TRUE),
                       numProducts = sample(1:10, 1000, replace = TRUE), 
                       OrderTotal = sample(1:100, 1000, replace = TRUE))

输出如下:

head(products)
  clientID  OrderDate category numProducts OrderTotal
1       90 2012-03-20        D           9         18
2       66 2012-08-19        A           3         50
3       45 2012-05-25        A          10         75
4       28 2012-01-01        D           4         27
5       71 2012-02-28        A           4         76
6       26 2012-01-28        C           8         89

我想要的结构看起来像这样:

          Category A                                                                    ...   Category E
ClientID  Jan2012numProducts  Jan2012OrderTotal  Feb2012numProducts  Feb2012OrderTotal  ...  Sep2012numProducts  Sep2012OrderTotal
1         12                  78                 6                   52                      0                   0
2         7                   218                3                   15                      1                   28
...
99999     20                  192                10                  100                     28                  156

我意识到列名可能会变长,看起来像AJan2012numProducts或AJan2012OrderTotal,这很好。

以下是我不清楚的程序 - 再次,我在文档或小插图中找不到它们:

1)zoo可以聚合多个观察区域吗?在这种情况下,我想在本月同时获得numProducts和OrderTotal的总和。即使zoo不能,我也可以使用merge函数并加入clientID和类别

2)zoo可以按因子(或多个因素)分组来执行聚合吗?我希望能够逐月查看clientID和category。

3)是否能够沿X轴创建具有类别和月份的数据框。如果没有,如果我可以通过clientID和类别将时间序列数据简单地组合在一起,那么我可以使用reshape使用cast来扩展时间序列。我需要将数据帧放到这个结构中:

head(df)
clientID   Month     category    numProducts  OrderTotal
1        2012-01-31  A           12           78
1        2012-01-31  B           0            0
....
99999    2012-09-30  D           6            71
99999    2012-09-30  E           1            28



cast(df, month~category, sum) (or something close to that)

这有可能吗?你能帮一些例子吗?

1 个答案:

答案 0 :(得分:0)

使用format.Datextabsftable的组合可以让您完全满足您的要求。我稍微简化了一下这个例子,但原则应该是明确的。如果您希望月份字段更短,则可以更改表对象中维度的名称,或者您可以创建月份列并重做所有工作。 (我承认我很难弄清楚'动物园'会如何进入这张照片。目前它看起来像一个简单的制表问题。虽然......我确信aggregate.zoo能够汇总多个标准并使用和作为聚合函数。)

首先是两个命令,然后是控制台会话输出:

prodtble <- xtabs(cbind(numProducts, OrderTotal) ~ clientID + 
                                                  format(OrderDate, "%b%Y") + 
                                                  category, 
                  data=products)
ftable(prodtbl, row.vars=c("category","clientID"))

现在输出:

> xtabs(cbind(numProducts, OrderTotal) ~ clientID + format(OrderDate, "%b%Y")+category, data=products)
, , category = A,  = numProducts

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1      23       0      16
       2       0       6      27
       3      30       0      21
       4      13      33      24
       5       5      20      12

, , category = B,  = numProducts

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1       8      27      23
       2       8      14       4
       3       0       5       6
       4       8      13      39
       5       3      23       9

, , category = C,  = numProducts

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1       0       6      20
       2      20      20       4
       3       0      17       0
       4      17      11       2
       5       7       3       8

, , category = A,  = OrderTotal

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1      40       0      41
       2       0       5      33
       3      48       0      40
       4      16      28      24
       5      23      42      29

, , category = B,  = OrderTotal

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1      14      24      19
       2      22      19      19
       3       0       2       4
       4      19      46      62
       5      10      38      10

, , category = C,  = OrderTotal

        format(OrderDate, "%b%Y")
clientID Feb2012 Jan2012 Mar2012
       1       0       2      39
       2      30      33       7
       3       0      44       0
       4      50      21      19
       5      16      14      28
# You could have skipped the printout by assigning to 'prodtable' in the step above.
# I thought is was useful pedagogically.

> prodtbl <- .Last.value

> ftable(prodtbl, row.vars=c("category","clientID"))
                  format(OrderDate, "%b%Y")     Feb2012                Jan2012                Mar2012           
                                            numProducts OrderTotal numProducts OrderTotal numProducts OrderTotal
category clientID                                                                                               
A        1                                           23         40           0          0          16         41
         2                                            0          0           6          5          27         33
         3                                           30         48           0          0          21         40
         4                                           13         16          33         28          24         24
         5                                            5         23          20         42          12         29
B        1                                            8         14          27         24          23         19
         2                                            8         22          14         19           4         19
         3                                            0          0           5          2           6          4
         4                                            8         19          13         46          39         62
         5                                            3         10          23         38           9         10
C        1                                            0          0           6          2          20         39
         2                                           20         30          20         33           4          7
         3                                            0          0          17         44           0          0
         4                                           17         50          11         21           2         19
         5                                            7         16           3         14           8         28

这是缩短的例子:

clients <- 1:5
dates <- seq(as.Date("2012/1/1"), as.Date("2012/3/31"), "days")
categories <- LETTERS[1:3]
products <- data.frame(clientID = sample(clients, 100, replace = TRUE), 
                       OrderDate = sample(dates, 100, replace = TRUE), 
                       category = sample(categories, 100, replace = TRUE),
                       numProducts = sample(1:10, 100, replace = TRUE), 
                       OrderTotal = sample(1:20, 100, replace = TRUE))