首页 > 解决方案 > 循环数组,保留值

问题描述

我有很多数据集,我需要具有相同的结构 - 相同的变量,相同的顺序。我有一个用作模板的数据集(下面代码中的“全部”)。通过在同一个 set 语句中列出模板数据集(obs=0)和特定数据集(下面代码中的“some”)来给出其他数据。这工作得很好。

然后我想遍历变量。如果其中一个缺失(如果它不存在于特定数据集中),则应将其设置为前一个变量的值。var2 应该从 var1 等获取值。这应该在每一行中完成。如果在单独的数据步骤中完成,这可以正常工作,但如果在上述相同的数据步骤中完成,则不起作用。

如果在同一数据步骤中完成,为缺失值插入的值将始终来自第 1 行。这是为什么呢?我可以在不使用其他数据步骤的情况下获得想要的结果吗?

/*  All the variables a complete data set should contain.*/
data all;
    format var1-var5 $20.;
run;

/*  Actual data have some of these variables, but not all. var1 is never missing, all other variables might be*/
data some;
    var1="Obs 1, Value 1";
    var4="Obs 1, Value 4";
    output;
    var1="Obs 2, Value 1";
    var4="Obs 2, Value 4";
    output;
run;

/*  Not working - The values inserted when the conditional is true are all from row 1*/
data dont_want;
    set all(obs=0) some;
    array chars{*} _character_;
    do i=1 to dim(chars);
        if missing(chars{i}) then chars{i}=chars{i-1};
    end;
    drop i;
run;

/*  Working*/
data temp;
    set all(obs=0) some;
run;

data want;
    set temp;
    array chars{*} _character_;
    do i=1 to dim(chars);
        if missing(chars{i}) then chars{i}=chars{i-1};
    end;
    drop i;
run;

标签: sas

解决方案


“额外”变量的值被保留,因为它们来自 ALL 数据集。源自输入数据集的任何变量都不会在数据步迭代开始时重置为缺失。由于这些变量不在某些数据集上,因此在从中读取观察值时它们不会改变。

只需添加代码即可将它们重置为丢失。如果您想在不知道变量名称的情况下执行此操作,则可以考虑重新排序代码。

您可以在编译器“看到”ALL 数据集但在运行时读取 SOME 数据集之前定义和清除数组。

data dont_want;
    if 0 then set all;
    array chars{*} _character_;
    call missing(of chars{*});
    set some;
    do i=2 to dim(chars);
        if missing(chars{i}) then chars{i}=chars{i-1};
    end;
    drop i;
run;

或者添加一个显式的 OUTPUT 语句并在之后重置它们。

data dont_want;
    set all(obs=0) some;
    array chars{*} _character_;
    do i=2 to dim(chars);
        if missing(chars{i}) then chars{i}=chars{i-1};
    end;
    drop i;
    output;
    call missing(of _all_);
run;

推荐阅读