2017-08-09 62 views
0

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

我的数据是这样的:

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,然后最后按变量名称的最后一位进行排序。 I.E. 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.... 

回答

1

两个问题。

首先,您在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; 
+0

为什么ORDER BY向后?另外,我的SUBSTR没有错。你可以简单地做一个长度 - N,SAS从那一点到这个字符串的其余部分。 I.E. '数据测试; 长度$ 3; 输入一个; datalines; abc ; 跑; proc sql; 创建表格新为 select substr(a,length(a)-0)as a1 from test; quit; proc print data = new;运行;' 产生'c',但现在我解释说,对于我自己,这仍然不支持1和2位数字 – DukeLuke

+1

您想要按数字和名称排序。否则,首先将所有名称分组,首先按照数字排序。尝试上面的代码,它会按照您的要求进行操作。 – DomPazz