【问题标题】:SAS multiple dataset and Coalesce functionSAS 多数据集和合并函数
【发布时间】:2018-05-04 20:31:28
【问题描述】:

早安,

我有不同格式的旧数据并用新数据更新它。想法是变量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 中的数据集是先加载的,然后再应用函数。 (在后一个数据语句中哪个起作用。显然不是……也许?

【问题讨论】:

    标签: sas dataset coalesce


    【解决方案1】:

    我认为更好的方法是在 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函数便宜)更简单。

    【讨论】:

    • true,这将是实现预期结果的更好方法。或者使用proc datasets 永久重命名旧文件。
    • 真+1。这个问题的动机主要是为了学习一些东西。我从来没有认为pdv 逻辑会是一个问题。 (嗯,现在很明显,事后。)
    【解决方案2】:

    @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;
    

    【讨论】:

      【解决方案3】:

      原因是 pdv 隐式保留了已“设置”的变量,并且在加载早期数据集(2015 年之前)时,wantedName 不会从 pdv 中刷新。

      编译器为其腾出空间(通过读取 set 语句中的所有数据集),但 set 命令不会(最初)替换 wantedName 的值。

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

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

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

      WantedName=COALESCE(1234, 4321); /* obs 2 */
      

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

      好问题!

      【讨论】:

        猜你喜欢
        • 2017-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-03
        • 2020-12-10
        • 2019-03-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多