在SAS中查找下一个非空值

在SAS中查找下一个非空值,sas,linear-interpolation,Sas,Linear Interpolation,我试图在面板集数据中线性插值。因此,如果变量的当前值为“”,我将在变量中找到下一个非零值 例如,如果X={1,2,,,,7),我想将7存储为变量“Y”,并将其中的滞后值X作为斜率的分子。有人能帮我完成这一步吗?有没有一种方法可以转置所有数据?当所有需要的数据都在一个观测值中时,这样的插值会容易得多。例如: data test; input x best12.; datalines; 1 2 . . . 7 ; run; proc transpose data = test out = te

我试图在面板集数据中线性插值。因此,如果变量的当前值为“”,我将在变量中找到下一个非零值


例如,如果X={1,2,,,,7),我想将7存储为变量“Y”,并将其中的滞后值X作为斜率的分子。有人能帮我完成这一步吗?

有没有一种方法可以转置所有数据?当所有需要的数据都在一个观测值中时,这样的插值会容易得多。例如:

data test;
input x best12.;
datalines;
1
2
.
.
.
7
;
run;

proc transpose data = test
  out = test2;
run;

data test3;
    set test2;
    array xvalues {*} COL1-COL6;
    array interpol {4,10} begin1-begin10 end1-end10 begposition1-begposition10 endposition1-endposition10;

    rangenum = 1;
* Find the endpoints of the missing ranges;
do i = 1 to dim(xvalues);
    if xvalues{i} ne . then lastknownx = xvalues{i};
    else do;
        interpol{1,rangenum} = lastknownx;
        if interpol{3,rangenum} = . then interpol{3,rangenum} = i - 1;
    end;

    if i > 1 and xvalues{i} ne . then do;
        if xvalues{i-1} = . then do;
            interpol{2,rangenum} = xvalues{i};
            interpol{4,rangenum} = i;
            rangenum = rangenum + 1;
        end;
    end;
end;

* Interpolate;

rangenum = 1;

do j = 1 to dim(xvalues);
    if xvalues{j} = . then do;
        xvalues{j} = interpol{1,rangenum} + (j-interpol{3,rangenum})*((interpol{2,rangenum}-interpol{1,rangenum})/(interpol{4,rangenum}-interpol{3,rangenum}));
    end;
    else if j > 1 and xvalues{j} ne . then do;
        if xvalues{j-1} = . then rangenum = rangenum + 1;
    end;
end;

keep col1-col6;

run;

每个观测值最多可以处理10个不同的缺失范围,不过您可以通过创建更大的数组来调整代码以处理更多的缺失范围。

是否有一种方法可以转置所有数据?当您需要的所有数据都在一个观测值中时,这样的插值更容易。如下所示:

data test;
input x best12.;
datalines;
1
2
.
.
.
7
;
run;

proc transpose data = test
  out = test2;
run;

data test3;
    set test2;
    array xvalues {*} COL1-COL6;
    array interpol {4,10} begin1-begin10 end1-end10 begposition1-begposition10 endposition1-endposition10;

    rangenum = 1;
* Find the endpoints of the missing ranges;
do i = 1 to dim(xvalues);
    if xvalues{i} ne . then lastknownx = xvalues{i};
    else do;
        interpol{1,rangenum} = lastknownx;
        if interpol{3,rangenum} = . then interpol{3,rangenum} = i - 1;
    end;

    if i > 1 and xvalues{i} ne . then do;
        if xvalues{i-1} = . then do;
            interpol{2,rangenum} = xvalues{i};
            interpol{4,rangenum} = i;
            rangenum = rangenum + 1;
        end;
    end;
end;

* Interpolate;

rangenum = 1;

do j = 1 to dim(xvalues);
    if xvalues{j} = . then do;
        xvalues{j} = interpol{1,rangenum} + (j-interpol{3,rangenum})*((interpol{2,rangenum}-interpol{1,rangenum})/(interpol{4,rangenum}-interpol{3,rangenum}));
    end;
    else if j > 1 and xvalues{j} ne . then do;
        if xvalues{j-1} = . then rangenum = rangenum + 1;
    end;
end;

keep col1-col6;

run;

每个观测值最多可以处理10个不同的缺失范围,不过您可以通过创建更大的数组来调整代码以处理更多的缺失范围。

SAS数据步骤从上到下一次读取一个数据集记录。因此,在记录i,它无法访问i+1,因为它尚未读取它;它只能访问i-1。假设您有带有变量x的数据集

data intrpl;
    retain _x;
    set yourdata;
    by x notsorted;
    if not missing(x) then do;
        _x = x;
        if last.x then do;
            slope = _x - lag(_x);
            output;
        end;
    end;
run;

如果x有很多值,转置可能会有点混乱,所以我推荐这种方法。我希望它能有所帮助!

SAS数据步骤从上到下一次读取一个数据集一条记录。因此在记录I,它无法访问I+1,因为它还没有读取它;它只能访问I-1。假设您有一个带有变量x的数据集

data intrpl;
    retain _x;
    set yourdata;
    by x notsorted;
    if not missing(x) then do;
        _x = x;
        if last.x then do;
            slope = _x - lag(_x);
            output;
        end;
    end;
run;

如果x具有很多值,则转置可能会变得有点混乱,因此我建议使用这种方法。我希望它能有所帮助!

如果您无法转置数据,以下是一种适用于给定示例的方法:

data test;
    input id $3. x best12.;
    datalines;
AAA 1
BBB 2
CCC .
DDD .
EEE .
FFF 7
;
run;

data test2;
    set test;
    n = _n_;
    if x ne .;
run;

data test3;
    set test2;
    lagx = lag(x);
    lagn = lag(n);
    if _n_ > 1 and n ne lagn + 1 then do;
        postiondiff = n - lagn;
        valuediff = x - lagx;
        do i = (lagx + ((x-lagx)/(n-lagn))) to x by ((x-lagx)/(n-lagn));
            x = i;
            output;
        end;
    end;
    else output;
    keep x;
run;

data test4;
    merge test test3 (rename = (x=newx));
run;

因此,我们基本上是用插值重建变量,然后将其重新合并到原始数据集中,而不使用by变量,这将使所有新的插值数据与缺失的点对齐。

如果您无法转换数据,以下是一种适用于给定示例的方法:

data test;
    input id $3. x best12.;
    datalines;
AAA 1
BBB 2
CCC .
DDD .
EEE .
FFF 7
;
run;

data test2;
    set test;
    n = _n_;
    if x ne .;
run;

data test3;
    set test2;
    lagx = lag(x);
    lagn = lag(n);
    if _n_ > 1 and n ne lagn + 1 then do;
        postiondiff = n - lagn;
        valuediff = x - lagx;
        do i = (lagx + ((x-lagx)/(n-lagn))) to x by ((x-lagx)/(n-lagn));
            x = i;
            output;
        end;
    end;
    else output;
    keep x;
run;

data test4;
    merge test test3 (rename = (x=newx));
run;
因此,我们基本上是用插值重建变量,然后将其重新合并到原始数据集中,而不使用by变量,这将使所有新插值数据与缺失点对齐