SAS/SQL 动态排序变量

SAS/SQL Ordering Variables Dynamically

我正在尝试以特定方式组织一个数据集,其中包含一个变化的变量列表。我遇到的问题是我并不总是知道我的数据集中将拥有的实际变量数。我之前在变量列表是静态的数据语句之后使用 PROC SQL 语句或 RETAIN 语句完成了此操作。

我的数据是这样的:

APPNUM   DATE   REASON1  REASON2 REASON3 REASON4 NAME1 NAME2 NAME3 NAME4
123    1/1/2017   X        Y        Z      A     Jon   Mary  Tom   Suzie

我希望它看起来像这样:

APPNUM   DATE   REASON1  NAME1 REASON2 NAME2 etc
123    1/1/2017   X       Jon   Y      Mary  etc

使用 sql 或保留语句很容易做到这一点。但是,我正在使用循环等将这些变量拉到一起,并且显示的变量数量取决于我的输入数据。有些日子可能有 20 个 REASON/NAME 实例,而其他日子可能每个都有 1 个实例。

我尝试了下面的代码来提取变量名列表,然后对 APPNUM、DATE 进行排序,最后按变量名的最后一位排序。 IE。 1,1,2,2,3,3 - 但我没有成功。该列表被正确存储 - 没有错误,但在解析 &VARLIST 的值时。他们没有按预期订购。有没有人尝试过并完成这个?

PROC SQL;
SELECT NAME INTO :VARLIST SEPARATED BY ','
FROM DICTIONARY.COLUMNS
WHERE LIBNAME = 'WORK'
AND MEMNAME = 'SFINAL'
ORDER BY NAME, SUBSTR(NAME,LENGTH(NAME)-1);
QUIT;

上面的代码会这样排序:

APPNUM, DATE, NAME1...2...3..., REASON1...2...3...

而不是:

APPNUM, DATE, NAME1, REASON1, NAME2, REASON2....

两个问题。

首先,您在 ORDER BY 上的顺序是倒序的。

其次,您的SUBSTR()调用不正确。最后你有一个任意长度的数字。你不知道会有多少个字符。最好的办法是读取该数字字符串,转换为数字,然后按此排序。

data test;
array name[20];
array reason[20];
format appnum best. date date9.;
run;

proc sql noprint;
SELECT  NAME INTO  :VARLIST SEPARATED BY ','
FROM DICTIONARY.COLUMNS
WHERE LIBNAME = 'WORK'
AND MEMNAME = 'TEST'
and (upcase(NAME) like 'NAME%' or upcase(NAME) like 'REASON%') 
ORDER BY input(compress(compress(name,'name'),'reason'),best.), NAME ;
quit;

%put &varlist;

proc sql noprint;
create table test2 as
select APPNUM, DATE, &varlist
from test;
quit;