SAS 多数据集和合并函数

Posted

技术标签:

【中文标题】SAS 多数据集和合并函数【英文标题】:SAS multiple dataset and Coalesce function 【发布时间】: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 中的数据集是先加载的,然后再应用函数。 (在后一个数据语句中哪个起作用。显然不是……也许?

【问题讨论】:

【参考方案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 变量的数据集。

好问题!

【讨论】:

以上是关于SAS 多数据集和合并函数的主要内容,如果未能解决你的问题,请参考以下文章

交织 SAS 数据集(按常见患者编号)

SAS编程基础 - 数据获取与数据集操作

SAS 对数据的拼接与串接

SAS Proc SQL 不存在查询与数据步骤 a=1 b=0

Sas程序优化使用较少的工作空间

我应该使用训练数据集的函数来处理训练数据集和测试数据集的缺失值吗