【问题标题】:Sliding normalising window in RR中的滑动归一化窗口
【发布时间】:2017-12-20 13:21:52
【问题描述】:

我有一个数据框,其中包含 7 个变量,我想对其应用滚动标准化窗口。我的数据框没有 NA 值,所有变量的长度都相同。

> head(CK0159U09A3,10)
            W1          W2         W3        W4         W5         W6         W7
1   1.37853716  0.01316304 -0.1363012 0.6895341 -0.7230930 -0.1310321 -0.4109521
2  -0.73032998  0.31212925  0.1654731 0.9187255 -0.8017260 -0.1619631 -0.4243575
3  -0.52130420  0.43831484  0.6088623 1.1183964 -0.8486971 -0.1970389 -0.4368820
4   0.55501096  0.13850401  1.1221211 1.2708212 -0.8701385 -0.2372061 -0.4490060
5  -0.06995122 -0.53842548  1.4592013 1.3581935 -0.8661200 -0.2791726 -0.4608654
6  -0.19984548 -0.78829431  1.4564180 1.3823090 -0.8431200 -0.3184653 -0.4722506
7   0.68935525  0.18733222  1.0158497 1.3344059 -0.8043461 -0.3526886 -0.4825229
8  -0.49540738  0.80663376  0.1774945 1.1800970 -0.7494087 -0.3803636 -0.4901212
9  -0.09501622 -0.17931684 -0.7074083 0.9312984 -0.6801124 -0.4008524 -0.4942994
10 -0.14939548 -0.68153738 -1.2723772 0.6054420 -0.5968207 -0.4149125 -0.4952316

我的窗口被定义为大小 3

windowSize <- 3

我想将大小 = 3 的滚动窗口应用于我的数据框中的每个变量。归一化函数使用以下逻辑:

  1. 计算整个变量的标准差(长度(CK0159U09A3[,1].....)
  2. 然后将大小 = 3 的窗口应用于前 3 个值并计算它们的平均值
  3. 对于窗口中的第一个值,它减去三个值的平均值,然后除以标准差
  4. 然后该函数递增 1,并对所有 7 列的接下来三个值执行相同的步骤。

我知道 zoo 中的 rollapply/r 函数,但我无法理解如何编写关于获取当前值并执行减法和除法然后递增到下一个值的部分。如果你还不能说,我不是一个强大的程序员。

我相信它已经在下面的第一个答案中被捕获,但是当滑动窗口到达列的末尾并且值小于窗口大小时,应该返回 NA。

任何帮助解决这个问题将不胜感激。

为了清楚起见,这里是我试图用数学实现的逻辑

1.3785 - ((1.378+(-0.7303)+(-0.5213)/windowSize))/S.D of column

-0.7303 - ((-0.7303+(-0.5213)+0.555)/windowSize))/S.D of column

-0.5213 - ((-0.5213+0.555+(-0.0699))/windowSize))/S.D of column

【问题讨论】:

  • 底部两行没有 2 个尾随值会怎样?如果你给出 expected output 会有所帮助;或许可以手动计算前几行,以便我们进行验证。
  • @r2evans,你说得对,我从来没有说过一旦值小于窗口大小会发生什么。我已经更新了原始帖子,指出应该退回 NA。感谢您的提醒。

标签: r dataframe sliding-window


【解决方案1】:

1)如果DF是输入data.frame,计算滚动均值,从原始数据帧中减去,然后将每一列除以对应的sd值。如果您不想要 NA 行,请使用 na.omit(out)

请注意,此问题的答案与此处相关:How to divide each row of a matrix by elements of a vector in R

library(zoo)

out <- t( t(DF - rollmean(DF, 3, fill = NA, align = "left")) / sapply(DF, sd))

给予:

> out
           W1          W2         W3           W4         W5        W6        W7
1   2.0571604 -0.46799047 -0.3798546 -0.782516058  0.7559711 0.3162800 0.4320913
2  -0.7668684  0.03065979 -0.5079677 -0.656126126  0.4270853 0.3599383 0.4083388
3  -0.7839578  0.82502267 -0.4947466 -0.466405606  0.1438538 0.3990324 0.3966334
4   0.7080855  1.03647378 -0.2435920 -0.236471919 -0.1148815 0.4020498 0.3856112
5  -0.3229973 -0.30756238  0.1618686 -0.000389918 -0.3137854 0.3680621 0.3629682
6  -0.3046393 -1.66132459  0.6238737  0.297421141 -0.4903858 0.3136170 0.3091448
7   1.0105062 -0.16328686  0.9294159  0.662844512 -0.6631908 0.2474401 0.2128288
8  -0.3830338  1.59900097  0.8471133  0.979199212 -0.8212911 0.1795721 0.1020336
9          NA          NA         NA           NA         NA        NA        NA
10         NA          NA         NA           NA         NA        NA        NA

更正问题中的公式,第 1 列中的前 3 个值是:

(1.3785 - (1.378+(-0.7303)+(-0.5213))/3)/sd(DF[, 1])
## [1] 2.057361
(-0.7303 - (-0.7303+(-0.5213)+0.555)/3)/sd(DF[, 1])
## -0.7668342
(-0.5213 - (-0.5213+0.555+(-0.0699))/3)/sd(DF[, 1])
## [1] -0.7839742

2) 另一种解决方案是定义一个函数,该函数在单个列上执行所需的操作,然后sapply 将其应用于每一列。

sapply(DF, function(x) (x - rollmean(x, 3, align = "left", fill = NA))/sd(x))

注意:可重现形式的输入是:

Lines <-  " W1          W2         W3        W4         W5         W6         W7
1   1.37853716  0.01316304 -0.1363012 0.6895341 -0.7230930 -0.1310321 -0.4109521
2  -0.73032998  0.31212925  0.1654731 0.9187255 -0.8017260 -0.1619631 -0.4243575
3  -0.52130420  0.43831484  0.6088623 1.1183964 -0.8486971 -0.1970389 -0.4368820
4   0.55501096  0.13850401  1.1221211 1.2708212 -0.8701385 -0.2372061 -0.4490060
5  -0.06995122 -0.53842548  1.4592013 1.3581935 -0.8661200 -0.2791726 -0.4608654
6  -0.19984548 -0.78829431  1.4564180 1.3823090 -0.8431200 -0.3184653 -0.4722506
7   0.68935525  0.18733222  1.0158497 1.3344059 -0.8043461 -0.3526886 -0.4825229
8  -0.49540738  0.80663376  0.1774945 1.1800970 -0.7494087 -0.3803636 -0.4901212
9  -0.09501622 -0.17931684 -0.7074083 0.9312984 -0.6801124 -0.4008524 -0.4942994
10 -0.14939548 -0.68153738 -1.2723772 0.6054420 -0.5968207 -0.4149125 -0.4952316"
DF <- read.table(text = Lines)

【讨论】:

  • 非常感谢您的快速回复,这是一个巨大的帮助。
猜你喜欢
  • 2013-04-03
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
相关资源
最近更新 更多