R 一种缺失数据插补算法

R 一种缺失数据插补算法,r,curve-fitting,R,Curve Fitting,我有一个矩阵M[I,j],其中大量NA代表2000-2013年期间许多城市地区的人口存量[I,]。假设人口以恒定速度增长,我想填写缺失的数据 我想运行一个循环,对于矩阵M的每一行I 1.使用所有未缺失的观测值计算平均增长率 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,

我有一个矩阵M[I,j],其中大量NA代表2000-2013年期间许多城市地区的人口存量[I,]。假设人口以恒定速度增长,我想填写缺失的数据

我想运行一个循环,对于矩阵M的每一行I 1.使用所有未缺失的观测值计算平均增长率 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)
由于城市1的平均增长率为4,城市2为3,城市3为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)
你知道我该怎么做吗

最好的


Clément

只是近似于增长率

  • 每个城市都有1D数组
    p[n]
    ,所以从这个开始(p作为人口)
  • 索引
    i={0,1,2…,n-1}
    表示某个恒定步长中的时间
  • 所以,如果增长率是恒定的(我们称之为
    m
    ),那么

因此,现在只需猜测或近似
m
,并最小化与每个已知点的距离

  • 作为起点,可以得到两个连续的已知值
  • m0=p[i+1]/p[i]
  • 然后围绕这个值循环,一次最小化所有已知值的误差
  • 如果你愿意,你也可以使用我的(C++)
如果您想更精确,请使用动态增长率

  • 例如插值三次曲线或样条曲线
  • 并添加曲线拟合或使用近似
< >强>这里C++示例(简单丑陋慢非精确…)< /强>

  • 可以添加一些舍入并稍微调整它
  • 您还可以计算asc和desc中的错误,以便更安全
  • 也可以通过使用由有效值包围的起点值而不是第一个有效条目来增强这一点
  • 或者分别计算每个NA间隙

我认为你在城市1中犯了一个错误,因为一旦它增长了
4
,而另一次只增长了
2
。此外,您所需的输出显示的增长率为
2
,而不是
4
(根据您的描述)。@DavidArenburg是的,您是对的,所有城市的增长率都是相同的,除非条目不代表同一时间。。。城市之间。。。我已经准备了一些代码来回答。非常感谢你的回答。我将尝试将其翻译成R语言,并让您不断更新。
p[1]=p[0]*m
p[2]=p[0]*(m^2)
p[3]=p[0]*(m^3)
p[i]=p[0]*(m^i)
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 ]