SAS 多数据集和 Coalesce 函数

SAS multiple dataset and Coalesce function

美好的一天,

我有不同格式的旧数据并用新数据更新。想法是变量 WantedName 已经用下划线 Wanted_Name 编写,而新数据没有下划线。不过我没什么大不了的。

编辑:WantedNameWanted_Name 是 SAS 日期。

原始数据:

year Wanted_Name 
2013  1234       
2013  4321       
2013  3241       

从 2015 年开始:

year WantedName 
2015 5678     
2015 8765
....

我试过逻辑:

%macro macro_env;
data _null_; 
    call symput ("curr_year", year(date()) ); 
run;

data long_data;
    set 
    %do year=2013 %to &curr_year.;
        data.history&year.
    %end;
    ;
    WantedName=COALESCE(WantedName, Wanted_Name);
run;
%mend macro_env;

没有。不工作。出于某种原因,它采用 Wanted_Name 的第一个值并将其粘贴到除新数据之外的整个数据范围内:

year Wanted_Name WantedName
2013  1234        1234
2013  4321        1234
2013  3241        1234
....
2015  .           5678     
2015  .           8765

现在我设法通过删除 coalesce 函数并添加额外的数据语句来解决问题:

data long_data;
    set 
    %do year=2013 %to &curr_year.;
        data.history&year.
    %end;
    ;
run;

data long_data;
    set long_data;
    WantedName=COALESCE(WantedName, Wanted_Name);
run;

问题:发生了什么或者为什么原来的 macro_env 不工作?

我认为 set 中的数据集是先加载然后应用函数的。 (这在后面的数据声明中起作用。显然不是......也许?

原因是 pdv 隐式保留了 "set" 的变量,并且 wantedName 在加载较早的数据集(2015 年之前)时未从 pdv 中刷新。

编译器为它做了一个space(通过读取set语句中的所有数据集)但是set命令并没有(最初)替换wantedName的值。

因此 - 当读取第一个观察值时,wantedname 缺失,应用 wanted_name 的第一个值。

WantedName=COALESCE(., 1234); /* obs 1 */

在第二次迭代中,wantedname 的值已被保留,因此用于每次后续迭代,直到读入包含 wantedname.

的数据集
WantedName=COALESCE(1234, 4321); /* obs 2 */

第二个示例从一开始就使用了一个具有 wantedname 变量的数据集。

好问题!

正如@Allan Bowe 的回答形式所解释的那样,问题是为数据集提供的变量会自动保留。所以你可以添加代码来清除它们。

data long_data;
  set data.history20: ; 
  WantedName=COALESCE(WantedName, Wanted_Name);
  output;
  call missing(wantedname,wanted_name);
run;

或者新建一个变量。

data long_data;
  set data.history20: ; 
  new_WantedName=COALESCE(WantedName, Wanted_Name);
  format new_WantedName date9. ;
  drop WantedName Wanted_Name ;
  rename new_WantedName = WantedName ;
run;

我认为更好的方法是在 set 语句中使用 rename 来处理它。

data long_data;
    set 
    %do year=2013 %to &curr_year.;

        data.history&year.
          %if &year lt 2015 %then %do;
           (rename=wanted_name=wantedname)
          %end;
    %end;
    ;
run;

更便宜(重命名比 coalesce 函数更便宜)和更简单。