SAS 多数据集和 Coalesce 函数
SAS multiple dataset and Coalesce function
美好的一天,
我有不同格式的旧数据并用新数据更新。想法是变量 WantedName
已经用下划线 Wanted_Name
编写,而新数据没有下划线。不过我没什么大不了的。
编辑:WantedName
和 Wanted_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
函数更便宜)和更简单。
美好的一天,
我有不同格式的旧数据并用新数据更新。想法是变量 WantedName
已经用下划线 Wanted_Name
编写,而新数据没有下划线。不过我没什么大不了的。
编辑:WantedName
和 Wanted_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
函数更便宜)和更简单。