首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R一种缺失数据的补足算法

R一种缺失数据的补足算法
EN

Stack Overflow用户
提问于 2015-05-06 18:04:36
回答 1查看 229关注 0票数 2

我有一个矩阵Mi,j,其中有大量的NA,表示在2000-2013期间的许多城市地区的人口存量i,j。假设人口以恒定的速度增长,我想完成缺失的数据。

我想运行一个循环,对于矩阵M1的每一行i。使用所有未丢失的观测值计算平均增长率2。使用推测值填充空白

生成示例数据集:

代码语言:javascript
运行
复制
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)

由于city1、city2和city3的平均增长率分别为4、3和2,因此相应的结果矩阵应为:

代码语言:javascript
运行
复制
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

EN

回答 1

Stack Overflow用户

发布于 2015-05-06 18:25:47

简单地近似增长率

每个城市有一个1D数组p[n],所以从p开始(p因为表示在某个恒定步长

  • 中的时间,所以如果增长率是恒定的(让我们称之为m),那么

p1=p*m p2=p*(m^2) p3=p*(m^3) pi=p*(m^i)

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

作为起点,你可以得到两个连续的已知values

  • m0=p[i+1]/p[i];

  • and,然后循环这个值,一次最小化所有已知值的误差。你也可以使用approx class (在C++中),如果你想要的话

如果您想要更精确,请使用动态增长率

  • 例如插值三次或样条曲线和添加曲线拟合或也使用近似...

Here C++示例(简单、丑陋、缓慢、不精确...)

代码语言:javascript
运行
复制
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;
        }
    }

结果:

代码语言:javascript
运行
复制
// 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间隙来增强此功能
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30073547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档