在两个动态日之间插值

时间:2017-08-17 03:07:16

标签: r dataframe interpolation

我们有一个每周更新的文件,其结构如下:

      ID            Code    Days  Yield
KZW1KM093436    NTK273_1343 4    2.1781
KZW1KD913708    NTK091_1370 11   2.1683
KZK1KY011222    MKM012_0122 17   2.1602
KZW1KM063603    NTK182_1360 32   2.1419
KZW1KM093477    NTK273_1347 32   2.1419
KZW1KD913740    NTK091_1374 39   2.1342
KZW1KM063629    NTK182_1362 46   2.1269
KZW1KM093501    NTK273_1350 53   2.1202

我每周需要Yields以下的静态数据点(天):

28
91
182
273
364
730
1825
2555
3640

当文件更新时,数据结构也会发生变化(按Days排序)。有几种可能的情况:

  • 如果数据的Days列中的值等于任何一个 我的Static数据中的值,然后我想采取相应的 来自Yield列的值。
  • 否则,我想从中获取最接近的上限和下限值 Days并获得插值Yield(例如,我的静态28天 在这个特殊情况下,我必须使用这两行:KZK1KY011222 MKM012_0122 17 2.1602KZW1KM063603 NTK182_1360 32 2.1419)。
  • 如果没有开始或结束值,则主要适用 到283640,我想从最近的Yield开始 Days

我正在考虑在Excel / VBA中进行此操作,但也希望看到R解决方案。任何帮助将不胜感激。

Yield的预期输出是根据以下公式计算的:

enter image description here

所以在28天的情况下我会Yield (28 - 17)*(2.1419-2.1602)/(32-17)+2.1602 = 2.1468

1 个答案:

答案 0 :(得分:2)

 A=read.table(text="ID            Code    Days  Yield
                KZW1KM093436    NTK273_1343 4   2.1781
                KZW1KD913708    NTK091_1370 11  2.1683
                KZK1KY011222    MKM012_0122 17  2.1602
                KZW1KM063603    NTK182_1360 32  2.1419
                KZW1KM093477    NTK273_1347 32  2.1419
                KZW1KD913740    NTK091_1374 39  2.1342
                KZW1KM063629    NTK182_1362 46  2.1269
                KZW1KM093501    NTK273_1350 53  2.1202",header=T)

 k=c(28L, 91L, 182L, 273L, 364L, 730L, 1825L, 2555L, 3640L)

现在首先找到要预测的值所在的区间

 funfun=function(x){
             if(x%in%A$Days)return(A[A$Days==x,3:4])
             v=findInterval(x,A$Days);na.omit(A[c(v,v+1),3:4])}

例如:

 funfun(28)
  Days  Yield
3   17 2.1602
4   32 2.1419
funfun(34)
  Days  Yield
5   32 2.1419
6   39 2.1342
funfun(4)
  Days  Yield
1    4 2.1781
funfun(0)
  Days  Yield
1    4 2.1781
funfun(345)
  Days  Yield
8   53 2.1202
 funfun(11)
  Days  Yield
2   11 2.1683

接下来,我们编写一个计算预测值的函数:

 funfun1=function(i){
   s=funfun(i)
   if(nrow(s)==1)return(s$Yield)
   (i-s$Days[1])*Reduce("/",rev(sapply(s,diff)))+s$Yield[1]
 }

sapply(k,funfun1)
[1] 2.14678 2.12020 2.12020 2.12020 2.12020 2.12020 2.12020 2.12020 2.12020

K中给出的大多数值都在我们所拥有的天数范围之外,因此只取最后一个值。如果我们有不同的价值怎么办?说:

  k=c(4,11,17,18,20,33,48,50)
  sapply(k,funfun1)
  [1] 2.178100 2.168300 2.160200 2.158980 2.156540 2.140800 2.124986 2.123071

我们看到数据中已有的那些值,我们得到了它们的收益率。在数据之上,我们获得数据中的最后产量以及我们根据需要估算的产量。

希望这会有所帮助