你可以使用长度为k的rollmedian吗?

时间:2016-06-06 15:52:02

标签: r

我有一个名为mydata的数据框,我想为滞后2到9添加滚动中位数。目前我正在使用rollmedianr,代码如下:

library(data.table)
library(zoo)
library(TTR)
date = seq(as.Date("2016-01-01"),as.Date("2016-01-10"),"day")
value =c(1,2,3,4,5,6,7,8,9,10)
mydata = data.frame (date, value)
mydata
setDT(mydata)[, paste0('MED',2:9) := lapply(2:9, function(x) rollmedianr(value, x, fill = rep(NA,x-1)) ),][]

         date value MED2 MED3 MED4 MED5 MED6 MED7 MED8 MED9
 1: 2016-01-01     1   NA   NA   NA   NA   NA   NA   NA   NA
 2: 2016-01-02     2    2   NA   NA   NA   NA   NA   NA   NA
 3: 2016-01-03     3    3    2   NA   NA   NA   NA   NA   NA
 4: 2016-01-04     4    4    3    3   NA   NA   NA   NA   NA
 5: 2016-01-05     5    5    4    4    3   NA   NA   NA   NA
 6: 2016-01-06     6    6    5    5    4    4   NA   NA   NA
 7: 2016-01-07     7    7    6    6    5    5    4   NA   NA
 8: 2016-01-08     8    8    7    7    6    6    5    5   NA
 9: 2016-01-09     9    9    8    8    7    7    6    6    5
10: 2016-01-10    10    2    9    3    8    4    7    5    6

但是在rollmedianr()函数的描述中,“k”必须是奇数,因此结果不正确。您可以看到第4行中的MED4显示“3”,但应该是中位数(c(1,2,3,4))的中位数,即2.5。我想计算偶数和奇数“k”的正确滚动中位数。

我认为这可行:

setDT(mydata)[, paste0('Calc',2:9) := lapply(2:9, function(x) rollapply(value,x,FUN="median",align="left"))][]

但它不正确,如下所示。 “Calc2”应该是NA,1.5,2等......

          date value Calc2 Calc3 Calc4 Calc5 Calc6 Calc7 Calc8 Calc9
 1: 2016-01-01     1   1.5     2   2.5     3   3.5     4   4.5     5
 2: 2016-01-02     2   2.5     3   3.5     4   4.5     5   5.5     6
 3: 2016-01-03     3   3.5     4   4.5     5   5.5     6   6.5     5
 4: 2016-01-04     4   4.5     5   5.5     6   6.5     7   4.5     6
 5: 2016-01-05     5   5.5     6   6.5     7   7.5     4   5.5     5
 6: 2016-01-06     6   6.5     7   7.5     8   3.5     5   6.5     6
 7: 2016-01-07     7   7.5     8   8.5     3   4.5     6   4.5     5
 8: 2016-01-08     8   8.5     9   2.5     4   5.5     7   5.5     6
 9: 2016-01-09     9   9.5     2   3.5     5   6.5     4   6.5     5
10: 2016-01-10    10   1.5     3   4.5     6   7.5     5   4.5     6
Warning messages:
1: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 9 items to be assigned to 10 items of column 'Calc2' (recycled leaving remainder of 1 items).
2: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 8 items to be assigned to 10 items of column 'Calc3' (recycled leaving remainder of 2 items).
3: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 7 items to be assigned to 10 items of column 'Calc4' (recycled leaving remainder of 3 items).
4: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 6 items to be assigned to 10 items of column 'Calc5' (recycled leaving remainder of 4 items).
5: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 4 items to be assigned to 10 items of column 'Calc7' (recycled leaving remainder of 2 items).
6: In `[.data.table`(setDT(mydata), , `:=`(paste0("Calc", 2:9), lapply(2:9,  :
  Supplied 3 items to be assigned to 10 items of column 'Calc8' (recycled leaving remainder of 1 items).

有什么想法?谢谢。

1 个答案:

答案 0 :(得分:0)

这个问题实际上并未说明所需的结果,但也许这就是你想要的。 (如果你想要左对齐,那么使用int main(int argc, char **argv) { if (argc == 1) { /* there are no extra arguments, handle this case */ } else { /* there are arguments, proceed to parse and handle them */ } } 而不是rollapply并添加rollapplyr - 由于问题中的一个示例使用了正确的对齐而另一个使用了左边,因此无法说明。 )

align="left"

,并提供:

setDT(mydata)[, paste0('MED',2:9) := 
                 lapply(2:9, rollapplyr, data = value, median, fill = NA),][]