2015-05-06 120 views
2

我有一個矩陣M [i,j],其中有大量的NA代表2000 - 2013年期間多個城市地區[i]的人口數量[i,j] 。假設人口以不變的速度增長,我想完成缺失的數據。R缺失數據插補的算法

我想運行一個循環,每一行的矩陣M 1. i的計算使用所有的非缺失觀察 2.填充在間隙中使用插補值

的平均增長速度生成的示例數據集:

city1=c(10,40,NA,NA,320,640); 
city2=c(NA,300,NA,1200,2400,NA); 
city3=c(NA,NA,4000,8000,16000,32000); 
mat=rbind(city1,city2,city3) 

由於平均增長率爲4 city1,3城2,和2請分享幫助,相應的結果矩陣應該是:

r.city1=c(10,40,80,160,320,640); 
r.city2=c(100,300,600,1200,2400,4800); 
r.city3=c(1000,2000,4000,8000,16000,32000); 
r.mat=rbind(city1,city2,city3) 

你知道我該怎麼做嗎?

最佳,

克萊門特

+1

我認爲'city1'中有一個錯誤,因爲它一旦以'4'增長,而另一次只以'2'增長。您的期望輸出也顯示'2'而不是'4'的增長率(根據您的描述)。 –

+0

@DavidArenburg是的,你是對的增長率是相同的所有城市,除非參賽作品不代表同一時間...城市之間...有一些代碼來回答 – Spektre

回答

1

只是近似的增長速度

  • 你有每個城市的一維數組p[n],以便與該(P人口)開始
  • 指數i={0,1,2...,n-1}意味着時間一些不變的步驟
  • 所以如果增長率不變(讓我們稱之爲m)然後

    p[1]=p[0]*m 
    p[2]=p[0]*(m^2) 
    p[3]=p[0]*(m^3) 
    p[i]=p[0]*(m^i) 
    

所以現在只是猜測或近似m和爲起點,你可以得到2個連續的已知值

  • m0=p[i+1]/p[i];
  • 每個已知點

    • 最小的距離
    • 然後圍繞此值進行循環,一次最小化所有已知值的誤差
    • 也可以使用礦approx class(在C++),如果你想

    如果你想成爲例如插值立方體或花鍵

  • 並添加曲線更精確的使用動態增長率

    • 擬合或也使用近似...

    這裏C + +示例(簡單醜陋慢非精確...)

    const int N=3; // cities 
    const int n=6; // years 
    int p[3][n]= 
        { 
        10, 40, -1, -1, 320, 640, // city 1 ... -1 = NA 
        -1,300, -1,1200, 2400, -1, // city 2 
        -1, -1,4000,8000,16000,32000, // city 3 
        }; 
    
    void estimate() 
        { 
        int i,I,*q,i0; 
        float m,m0,m1,dm,d,e,mm; 
        for (I=0;I<N;I++) // all cities 
         { 
         q=p[I];   // pointer to actual city 
         // avg growth rate 
         for (m0=0.0,m1=0.0,i=1;i<n;i++) 
         if ((q[i]>0)&&(q[i-1]>0)) 
          { m0+=q[i]/q[i-1]; m1++; } 
         if (m1<0.5) continue; // skip this city if avg m not found 
         m0/=m1; 
         // find m more closelly on interval <0.5*m0,2.0*m0> 
         m1=2.0*m0; m0=0.5*m0; dm=(m1-m0)*0.001; 
         for (m=-1.0,e=0.0;m0<=m1;m0+=dm) 
          { 
          // find first valid number 
          for (mm=-1,i=0;i<n;i++) 
          if (q[i]>0) { mm=q[i]; break; } 
          // comute abs error for current m0 
          for (d=0.0;i<n;i++,mm*=m0) 
          if (q[i]>0) d+=fabs(mm-q[i]); 
          // remember the best solution 
          if ((m<0.0)||(e>d)) { m=m0; e=d; } 
          } 
         // now compute missing data using m 
         // ascending 
         for (mm=-1,i=0;i<n;i++) if (q[i]>0) { mm=q[i]; break; } 
         for (;i<n;i++,mm*=m) if (q[i]<0) q[i]=mm; 
         // descending 
         for (mm=-1,i=0;i<n;i++) if (q[i]>0) { mm=q[i]; break; } 
         for (;i>=0;i--,mm/=m) if (q[i]<0) q[i]=mm; 
         } 
        } 
    

    結果:

    // input 
    [ 10 40 NA NA 320 640 ] 
    [ NA 300 NA 1200 2400 NA ] 
    [ NA NA 4000 8000 16000 32000 ] 
    // output 
    [ 10 40 52 121 320 640 ] 
    [ 150 300 599 1200 2400 4790 ] 
    [ 1000 2000 4000 8000 16000 32000 ] 
    
    • 可以添加一些圓角,並調整它有點
    • 也可以計算在這兩個ASC和DESC爲了更安全的錯誤
    • 也可以通過使用包圍有效值而非第一個有效條目的起點值來增強此效果
    • 或通過分別計算每個NA間隙
  • +0

    非常感謝您的答案。我將嘗試將它翻譯成R語言並讓您更新。 – goclem