SAS-通过编程识别表示日期/时间/日期时间的数字变量
我试图找到一种方法,从包含许多数字或字符类型变量的任意数据集中识别表示日期、时间或日期时间的数字变量子集。目标是有一个宏或模板,我可以对任何给定的数据集运行。我相信这些变量的SAS格式应该正确地表示变量是什么,但我正在尝试看看是否可以避免创建一些代码来解析SAS格式的文本以获得任何适用的格式名称 我最初认为应该可以执行以下操作来获取数据集的SAS格式,然后根据返回为date/time/datetime的列执行各种操作SAS-通过编程识别表示日期/时间/日期时间的数字变量,sas,Sas,我试图找到一种方法,从包含许多数字或字符类型变量的任意数据集中识别表示日期、时间或日期时间的数字变量子集。目标是有一个宏或模板,我可以对任何给定的数据集运行。我相信这些变量的SAS格式应该正确地表示变量是什么,但我正在尝试看看是否可以避免创建一些代码来解析SAS格式的文本以获得任何适用的格式名称 我最初认为应该可以执行以下操作来获取数据集的SAS格式,然后根据返回为date/time/datetime的列执行各种操作 PROC SQL; CREATE TABLE lib_X.Dataset
PROC SQL;
CREATE TABLE lib_X.Dataset_A AS
SELECT tbl_CL.LIBNAME
,tbl_CL.MEMNAME AS TABLE_NAME
,tbl_CL.NAME AS COLUMN_NAME
,tbl_CL.FORMAT AS SAS_Format
,tbl_CL.TYPE AS SAS_Type
,tbl_CL.varnum
,tbl_CL.LENGTH
FROM DICTIONARY.COLUMNS AS tbl_CL
WHERE tbl_CL.MEMNAME = %UPCASE("&SAS_DatasetNm")
AND tbl_CL.LIBNAME = %UPCASE("&SAS_LibNm");
QUIT;
其次是:
DATA lib_X.Dataset_A;
SET lib_X.Dataset_A;
IF FCN_FORMAT_TYPE(SAS_Format) = "DATETIME"
THEN ...;
RUN;
其中,FCN_FORMAT_TYPE
函数是检查SAS格式并返回变量是哪一个(字符、数字、日期/时间或ISO 8601)的函数,但似乎没有一个现有函数可以执行此操作。也许还有另一种方法可以奏效
当前在Linux服务器上的SAS 9.4 M2上运行。代码主要通过批处理文件使用,但也可能通过企业指南(如7.1或6.1)使用。没有现成的解决方案,但这里有一个可行的解决方案 为了简单起见,我们只处理日期,不包括时间和日期时间格式。该解决方案可以很容易地推广到包括这些 作为第一步,您将制定过滤器,以选择您可能期望的合理日期格式。下面是一个查询示例,它将匹配大约100种SAS日期格式
proc sql;
create table fmts as
select fmtname
from sashelp.vformat
where fmttype = "F"
and fmtname not like '$%'
and prxmatch("/(DATE|YY|YEAR)/",fmtname)
and not prxmatch("/(DT|TIME)/",fmtname)
order by fmtname;
quit;
微调WHERE过滤器后,可以在如下宏例程中使用它,其中第三个参数vmname
是要存储日期列名的全局宏变量的名称
%macro getDateCols(libname, dataset, vmname);
%global &vmname;
proc sql noprint;
select name
into :&vmname separated by ", " /* Use ", " or " " depending on your needs */
from dictionary.columns
where libname = upcase("&libname")
and memname = upcase("&dataset")
and format not like '$%'
and prxmatch("/(DATE|YY|YEAR|MONTH|DAY|WEEK)/", format)
and not prxmatch("/(DT|TIME)/", format);
quit;
%mend getDateCols;
调用宏后,应将列名HireDate存储在&dsdates
中:
%getDateCols(sasuser, empdata, dsdates);
%put &dsdates;
然后可以在proc sql中使用宏变量,例如
proc sql;
select &dsdates
from sasuser.empdata;
quit;
Dominic的回答让我想到了如何解决这个问题,使用了相同的通用方法,但将它放在PROC FCMP函数中,而不是宏中
PROC FCMP OUTLIB=LIB_X.FCMP_FUNCS.Format_Category_ID;
FUNCTION Format_Category(VAR_Format $, VAR_Type $) $ 16
GROUP = 'Format Category ID'
LABEL = 'Pass SAS variable type and format as CHAR and it will return what sort of variable it is.
Breaks down date/time/dt formats into independent categories.';
LENGTH FORMAT_CATEGORY $16;
SELECT;
WHEN (MISSING(VAR_Format)) FORMAT_CATEGORY = 'MISSING_FORMAT';
WHEN (VAR_Type = 'CHAR') FORMAT_CATEGORY = 'CHARACTER_FORMAT';
WHEN (PRXMATCH("/S370FZDT/", VAR_Format)) FORMAT_CATEGORY = 'NUMERIC_FORMAT';
WHEN (PRXMATCH("/8601/", VAR_Format)) FORMAT_CATEGORY = 'ISO_8601_FORMAT';
WHEN (PRXMATCH("/(DT|DATEAMPM|DATETIME)/", VAR_Format)) FORMAT_CATEGORY = 'DATETIME_FORMAT';
WHEN (PRXMATCH("/(HHMM|HOUR|MMSS|TIME|TOD)/", VAR_Format)) FORMAT_CATEGORY = 'TIME_FORMAT';
WHEN (PRXMATCH("/(DAT|DAY|YY|DOW|JUL|MON|QTR|WEEK|YEAR)/", VAR_Format)) FORMAT_CATEGORY = 'DATE_FORMAT';
WHEN (VAR_Type = 'NUM') FORMAT_CATEGORY = 'NUMERIC_FORMAT';
OTHERWISE FORMAT_CATEGORY = 'UNKNOWN';
END;
RETURN(FORMAT_CATEGORY);
ENDSUB;
它肯定不是防弹的,但它对我的目的起了作用,希望对其他人有用。我要补充的最大警告是,处理用户定义的格式将是touch-and-go,因为它只是解析作为字符变量传递的SAS格式,因此如果名称与我正在使用的正则表达式重叠,那么所有赌注都是无效的