SAS 保留声明
SAS retain statement
假设我有一个包含三个变量的数据集:
ID 年份 状态
1 2017 年
1 2017 年
1 2018 年
1 2018 年
2 2017 年
2 2017 年
2 2018 年
2 2018 年 N
我想创建一个名为 NEW 的第四列,它具有三个可能的值('Yonly' 'Nonly' 和 'yesno')。在上面的示例中,输出将是:
ID 年份 状态 新
1 2017 年
1 2017 N 是 否
1 2018 N
1 2018 Y 是否
2 2017 年
2 2017 是的
2 2018 N
2 2018 N 仅
注意:可能有缺失数据。到目前为止我的解决方案是错误的:
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。
这与您所做的大致相同,但条件语句最好更像这样。
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
第一行的值,然后在最后一行根据这两个变量考虑要做什么 - 这样就相当简单了。
确保定义 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 ;
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;
假设我有一个包含三个变量的数据集:
ID 年份 状态
1 2017 年
1 2017 年
1 2018 年
1 2018 年
2 2017 年
2 2017 年
2 2018 年
2 2018 年 N
我想创建一个名为 NEW 的第四列,它具有三个可能的值('Yonly' 'Nonly' 和 'yesno')。在上面的示例中,输出将是:
ID 年份 状态 新
1 2017 年
1 2017 N 是 否
1 2018 N
1 2018 Y 是否
2 2017 年
2 2017 是的
2 2018 N
2 2018 N 仅
注意:可能有缺失数据。到目前为止我的解决方案是错误的:
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。
这与您所做的大致相同,但条件语句最好更像这样。
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
第一行的值,然后在最后一行根据这两个变量考虑要做什么 - 这样就相当简单了。
确保定义 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 ;
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;