SAS保留声明

时间:2017-02-24 14:38:56

标签: if-statement sas retain

假设我有一个包含三个变量的数据集:
ID年份状态
1 2017 Y.
1 2017 N.
1 2018 N.
1 2018 Y.
2 2017 Y.
2017年2月
2 2018 N.
2 2018 N

我想创建一个名为NEW的第四列,它有三个可能的值('Yonly''Nonly'和'yesno')。在上面的示例中,输出将是:
ID年份状态新
1 2017 Y.
1 2017年N yesno
1 2018 N.
1 2018年Y yesno
2 2017 Y.
2 2017年是的
2 2018 N.
2 2018 N noonly

注意:可能缺少数据。到目前为止,我的解决方案是错误的:

retain tmp '';
by ID Year;
if Status='Y' then tmp='Yonly';
if Status='N' then tmp='Nonly';
if tmp='Yonly' and Status='N' then tmp='yesno';
  if tmp='Nonly' and Status='Y' then tmp='yesno';
if last.Year=1 then NEW=tmp;

请帮帮忙?任何方法都可以,你不必使用RETAIN。

2 个答案:

答案 0 :(得分:1)

这与你正在做的事情一致,但更好的做条件就是这样。

data want;
  set have;
  by id year;
  retain last_status;
  if first.year then last_status = status;
  if last.year then do;
    if status = last_status or missing(last_status) then new=cats(status,'only');
    else if missing(status) then new=cats(last_status,'only');
    else new='yesno';
  end;
run;

retain来自第一行的值,然后是最后一行,只考虑基于这两个变量做什么 - 这种方式非常简单。

答案 1 :(得分:1)

确保定义TMP的长度。您的当前代码会将TMP的长度设置为1,因为第一次使用是RETAIN语句中列出的初始值。

您在启动新组时缺少初始化步骤。

if first.year then tmp=' ';

您的方法只能在每个组的最后一条记录上设置结果。如果您希望组中的所有观察值具有相同的值,那么我建议使用双DOW循环。第一个循环可用于查看是否有任何' Y'或者' N'状态。然后你可以计算你的新变量。然后第二个循环将再次读取该组的数据并将值写出。由于组的所有观察都是在单个数据步骤迭代中处理的,因此无需使用RETAIN。

data want ;
  do until (last.year) ;
    set have ;
    by id year ;
    y = y or (status='Y');
    n = n or (status='N');
  end;
  length new $8;
  if Y and N then new='yesno';
  else if Y then new='yesonly';
  else if N then new='noonly';
  else new='none';
  drop y n ;
  do until (last.year) ;
    set have ;
    by id year ;
    output ;
  end;
run;