【问题标题】:Reshape a dataframe into stacks of average values将数据框重塑为平均值堆栈
【发布时间】:2014-04-12 17:51:02
【问题描述】:

我已经掌握了一些需要转换 i R 的数据。数据如下所示:

df <- data.frame(time = 1:100, value = runif(100, min = -20, max = 20))

我想做的是将数据转换为包含运行均值的矩阵,最多可提前 5 个时间段。这很难解释,但一个例子就是这样。

原始数据

time value
1      2
2      7 
3      8
4     19
5     -5
6    -15
7     4 
8     6
9     12
10    20

结果将是这个矩阵/数据框。

time  mean-value(5)      mean-value(4)    mean-value(3)   mean-value(2)    Mean-value(1)
1     (2+7+8+19-5)/5     (2+7+8+19)/4     (2+7+8)/3       (2+7)/2          2/1
2     (7+8+19-5-15)/5    (7+8+19-5)/4     (7+8+19)/3      (7+8)/2          7/1
3     (8+19-5-15+4)/5    .....
....
....
96    na                 numbers/4         numbers/3      numbers/2        numbers/1
97    na                 na                numbers/3       .....                    

我完全不知所措,我尝试了一些重塑,但它不正确。最后,如果没有足够的时间提前观察来计算,它也应该只给出 NA。

【问题讨论】:

标签: r reshape


【解决方案1】:

这是使用data.table 的一种方式。这个答案很可能会有所改进,甚至可能会有更好的答案。

获取data.table:

require(data.table) ## >= 1.9.2
dat <- read.table(header=TRUE, text="time value
         1     2
         2     7 
         3     8
         4    19
         5    -5
         6   -15
         7     4 
         8     6
         9    12
        10    20")

# convert to `data.table` by reference:
setDT(dat)

生成所有手段:

N = 5L
grp = seq_len(N);
ans = dat[, { 
              ix = .I:(.I+N-1L);
              vx = cumsum(dat$value[ix]);
              list(grp=grp, val=rev(vx/grp))
            }, by=time]

查看?data.table 了解.I(这是一个特殊变量,包含dat 对应每个组的行号)。

将其转换为宽格式:

dcast.data.table(ans, time ~ grp, value.var="val")

    time   1     2          3     4   5
 1:    1 6.2  9.00  5.6666667   4.5   2
 2:    2 2.8  7.25 11.3333333   7.5   7
 3:    3 2.2  1.75  7.3333333  13.5   8
 4:    4 1.8  0.75 -0.3333333   7.0  19
 5:    5 0.4 -2.50 -5.3333333 -10.0  -5
 6:    6 5.4  1.75 -1.6666667  -5.5 -15
 7:    7  NA 10.50  7.3333333   5.0   4
 8:    8  NA    NA 12.6666667   9.0   6
 9:    9  NA    NA         NA  16.0  12
10:   10  NA    NA         NA    NA  20

【讨论】:

    【解决方案2】:

    改编answer here,你可以很容易地使用filter得到你想要的:

    sapply(5:1, function(z) rev(filter(rev(df$value), rep(1/z,z), sides=1)))
    

    这是您的示例数据的结果:

          [,1]  [,2]       [,3]  [,4] [,5]
     [1,]  6.2  9.00  5.6666667   4.5    2
     [2,]  2.8  7.25 11.3333333   7.5    7
     [3,]  2.2  1.75  7.3333333  13.5    8
     [4,]  1.8  0.75 -0.3333333   7.0   19
     [5,]  0.4 -2.50 -5.3333333 -10.0   -5
     [6,]  5.4  1.75 -1.6666667  -5.5  -15
     [7,]   NA 10.50  7.3333333   5.0    4
     [8,]   NA    NA 12.6666667   9.0    6
     [9,]   NA    NA         NA  16.0   12
    [10,]   NA    NA         NA    NA   20
    

    【讨论】:

      猜你喜欢
      • 2015-08-22
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多