SAS 年份函数在宏内部不起作用
SAS year function not working inside macro
你好,我正在尝试使用特定日期格式访问库中的列,并在我的宏代码中的列上使用年份函数,但它会产生重复值...但是年份函数显示重复值并且未提供所需的结果。我的代码应该 return 只有输入日期的年份。
%macro dteyear(lib=,outdsn=);
proc sql noprint;
select distinct catx(".",libname,memname), name
into :dsns separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib") and format=('YYMMDD10.')
order by 1;
quit;
%put &dsns;
%put &varname;
%local olddsn curdsn curvbl i;
data &outdsn.;
set
%let olddsn=;
%do i=1 %to &sqlobs;
%let curdsn=%scan(&dsns,&i,%str( ));
%let curvbl=%scan(&varname,&i,%str( ));
%if &curdsn NE &olddsn
%then %do;
%if &olddsn NE
%then %do;
)
%end;
%let olddsn=&curdsn.;
&curdsn (keep=&curvbl
%end;
%else %do;
&curvbl
%end;
%end;
);
%do i=1 %to &sqlobs;
%scan(&varname,&i,%str( ))=year(&varname.);
%end;
run;
proc print data=&outdsn;run;
%MEND;
%dteyear(lib=dte3,outdsn=dtetst);
the input data is as follows
1975-12-04
1977-11-03
1989-09-15
1998-06-17
1999-05-31
2000-08-14
2001-03-11
2007-03-11
2007-12-28
2008-10-07
2009-12-03
我的代码的重复输出是-->
Obs RFDTC
1 1965-05-19
2 1965-05-19
3 1965-05-19
4 1965-05-19
5 1965-05-19
6 1965-05-19
7 1965-05-19
8 1965-05-19
9 1965-05-19
10 1965-05-19
11 1965-05-19
12 1965-05-19
13 1965-05-19
基本问题是 YEAR()
函数 returns 一个 4 位数字,变量的格式是 YYMMDD10.,所以结果被格式化为非常接近 1960 的 SAS 日期( SAS 的开端)。
我在下面的代码中所做的是将格式更改为 4.0,因此它显示为 4 位数字。
如果您想访问原始日期变量,则必须为年份创建一个新变量。我会把它留给你。
还有一个问题 -- 即,YEAR(&varname.)
插入了整个变量列表,而不仅仅是您正在使用的那个。如果只有一个日期变量,它会起作用,但如果有多个,则不起作用。我也解决了这个问题。
%macro dteyear(lib=,outdsn=);
proc sql noprint;
select distinct catx(".",libname,memname), name
into :dsns separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib") and format=('YYMMDD10.')
order by 1;
quit;
%put &dsns;
%put &varname;
%local olddsn curdsn curvbl i;
data &outdsn.;
set
%let olddsn=;
%do i=1 %to &sqlobs;
%let curdsn=%scan(&dsns,&i,%str( ));
%let curvbl=%scan(&varname,&i,%str( ));
%if &curdsn NE &olddsn
%then %do;
%if &olddsn NE
%then %do;
)
%end;
%let olddsn=&curdsn.;
&curdsn (keep=&curvbl
%end;
%else %do;
&curvbl
%end;
%end;
);
%do i=1 %to &sqlobs;
%let curvbl=%scan(&varname,&i,%str( ));
&curvbl=year(&curvbl.);
format &curvbl 4.0;
%end;
run;
proc print data=&outdsn;run;
%MEND;
data have;
input datevar yymmdd10.;
format datevar yymmdd10.;
cards;
1975-12-04
1977-11-03
1989-09-15
1998-06-17
1999-05-31
2000-08-14
2001-03-11
2007-03-11
2007-12-28
2008-10-07
2009-12-03
run;
options mprint;
%dteyear(lib=work,outdsn=want)
那么结果是:
Obs datevar
1 1975
2 1977
3 1989
4 1998
5 1999
6 2000
7 2001
8 2007
9 2007
10 2008
11 2009
要将日期值转换为年份,您可以使用 YEAR() 函数,但您还需要更改附加到变量的格式,因为您基本上将存储在其中的值除以 365 以进行转换从天数到年数。
rfdtc = year(rfdtc);
format rfdtc 4. ;
您的宏试图从多个数据集中读取多个变量并生成单个输出数据集。我不确定生成的数据集对您有多大价值,因为它看起来像一个包含缺失值的棋盘。此外,如果相同的变量名称出现在多个输入数据集中,您将获得损坏的值,因为将 YEAR() 函数应用于已从日期值转换为年份值的值。
例如,您最终可能会生成这样的数据步骤:
data WANT ;
set ds1 (keep=datevar1)
ds1 (keep=datevar2)
ds2 (keep=datevar3)
ds3 (keep=datevar3)
;
datevar1=year(datevar1);
datevar2=year(datevar2);
datevar3=year(datevar3);
datevar3=year(datevar3);
format datevar1 datevar2 datevar3 datevar3 4.;
run;
由于输入数据集 DS2 和 DS3 都有一个名为 DATEVAR3 的变量,您将对值应用 YEAR() 函数两次。这会将所有内容转换为 1965 年。
要消除 运行 YEAR() 函数多次处理相同值并丢失实际年份的问题,也许您只想应用 YEAR.
格式而不是转换存储值.
format datevar1 datevar2 datevar3 datevar4 year. ;
这仍然会留下不同的基础日期值。如果您真的需要值相同,也许您可以将值转换为一年的第一天?您可以使用 INTNX()
函数
datevar1 = intnx('year',datevar1,0,'b');
或MDY()
函数
datevar1 = mdy(1,1,year(datevar1));
你好,我正在尝试使用特定日期格式访问库中的列,并在我的宏代码中的列上使用年份函数,但它会产生重复值...但是年份函数显示重复值并且未提供所需的结果。我的代码应该 return 只有输入日期的年份。
%macro dteyear(lib=,outdsn=);
proc sql noprint;
select distinct catx(".",libname,memname), name
into :dsns separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib") and format=('YYMMDD10.')
order by 1;
quit;
%put &dsns;
%put &varname;
%local olddsn curdsn curvbl i;
data &outdsn.;
set
%let olddsn=;
%do i=1 %to &sqlobs;
%let curdsn=%scan(&dsns,&i,%str( ));
%let curvbl=%scan(&varname,&i,%str( ));
%if &curdsn NE &olddsn
%then %do;
%if &olddsn NE
%then %do;
)
%end;
%let olddsn=&curdsn.;
&curdsn (keep=&curvbl
%end;
%else %do;
&curvbl
%end;
%end;
);
%do i=1 %to &sqlobs;
%scan(&varname,&i,%str( ))=year(&varname.);
%end;
run;
proc print data=&outdsn;run;
%MEND;
%dteyear(lib=dte3,outdsn=dtetst);
the input data is as follows
1975-12-04
1977-11-03
1989-09-15
1998-06-17
1999-05-31
2000-08-14
2001-03-11
2007-03-11
2007-12-28
2008-10-07
2009-12-03
我的代码的重复输出是-->
Obs RFDTC
1 1965-05-19
2 1965-05-19
3 1965-05-19
4 1965-05-19
5 1965-05-19
6 1965-05-19
7 1965-05-19
8 1965-05-19
9 1965-05-19
10 1965-05-19
11 1965-05-19
12 1965-05-19
13 1965-05-19
基本问题是 YEAR()
函数 returns 一个 4 位数字,变量的格式是 YYMMDD10.,所以结果被格式化为非常接近 1960 的 SAS 日期( SAS 的开端)。
我在下面的代码中所做的是将格式更改为 4.0,因此它显示为 4 位数字。
如果您想访问原始日期变量,则必须为年份创建一个新变量。我会把它留给你。
还有一个问题 -- 即,YEAR(&varname.)
插入了整个变量列表,而不仅仅是您正在使用的那个。如果只有一个日期变量,它会起作用,但如果有多个,则不起作用。我也解决了这个问题。
%macro dteyear(lib=,outdsn=);
proc sql noprint;
select distinct catx(".",libname,memname), name
into :dsns separated by " ", :varname separated by " "
from dictionary.columns
where libname = upcase("&lib") and format=('YYMMDD10.')
order by 1;
quit;
%put &dsns;
%put &varname;
%local olddsn curdsn curvbl i;
data &outdsn.;
set
%let olddsn=;
%do i=1 %to &sqlobs;
%let curdsn=%scan(&dsns,&i,%str( ));
%let curvbl=%scan(&varname,&i,%str( ));
%if &curdsn NE &olddsn
%then %do;
%if &olddsn NE
%then %do;
)
%end;
%let olddsn=&curdsn.;
&curdsn (keep=&curvbl
%end;
%else %do;
&curvbl
%end;
%end;
);
%do i=1 %to &sqlobs;
%let curvbl=%scan(&varname,&i,%str( ));
&curvbl=year(&curvbl.);
format &curvbl 4.0;
%end;
run;
proc print data=&outdsn;run;
%MEND;
data have;
input datevar yymmdd10.;
format datevar yymmdd10.;
cards;
1975-12-04
1977-11-03
1989-09-15
1998-06-17
1999-05-31
2000-08-14
2001-03-11
2007-03-11
2007-12-28
2008-10-07
2009-12-03
run;
options mprint;
%dteyear(lib=work,outdsn=want)
那么结果是:
Obs datevar
1 1975
2 1977
3 1989
4 1998
5 1999
6 2000
7 2001
8 2007
9 2007
10 2008
11 2009
要将日期值转换为年份,您可以使用 YEAR() 函数,但您还需要更改附加到变量的格式,因为您基本上将存储在其中的值除以 365 以进行转换从天数到年数。
rfdtc = year(rfdtc);
format rfdtc 4. ;
您的宏试图从多个数据集中读取多个变量并生成单个输出数据集。我不确定生成的数据集对您有多大价值,因为它看起来像一个包含缺失值的棋盘。此外,如果相同的变量名称出现在多个输入数据集中,您将获得损坏的值,因为将 YEAR() 函数应用于已从日期值转换为年份值的值。
例如,您最终可能会生成这样的数据步骤:
data WANT ;
set ds1 (keep=datevar1)
ds1 (keep=datevar2)
ds2 (keep=datevar3)
ds3 (keep=datevar3)
;
datevar1=year(datevar1);
datevar2=year(datevar2);
datevar3=year(datevar3);
datevar3=year(datevar3);
format datevar1 datevar2 datevar3 datevar3 4.;
run;
由于输入数据集 DS2 和 DS3 都有一个名为 DATEVAR3 的变量,您将对值应用 YEAR() 函数两次。这会将所有内容转换为 1965 年。
要消除 运行 YEAR() 函数多次处理相同值并丢失实际年份的问题,也许您只想应用 YEAR.
格式而不是转换存储值.
format datevar1 datevar2 datevar3 datevar4 year. ;
这仍然会留下不同的基础日期值。如果您真的需要值相同,也许您可以将值转换为一年的第一天?您可以使用 INTNX()
函数
datevar1 = intnx('year',datevar1,0,'b');
或MDY()
函数
datevar1 = mdy(1,1,year(datevar1));