2017-05-05 173 views
0

我试图根据数据集中一列字符串创建一组标志。该字符串有成千上万的唯一值,但我想创建只有一个小子集(比如10)的标志。我想使用SAS宏变量来做到这一点。我尝试了许多不同的方法,其中没有一个能够奏效。这里是一个似乎最简单和最合乎逻辑的我的代码,但它仍然没有工作:使用SAS宏变量在PROC中创建变量名称SQL

%let Px1='12345'; 

PROC SQL; 

CREATE TABLE CLAIM1 AS 
SELECT 

b.MEMBERID 
, b.ENROL_MN 
, CASE WHEN (a.PROCEDURE = &Px1.) THEN 1 ELSE 0 END AS CPT_+&Px1. 
, a.DX1 
, a.DX2 
, a.DX3 
, a.DX4 

FROM ENROLLMENT as b 
left join CLAIMS as a 
on a.MEMBERID = b.MEMBERID; 

QUIT; 

显然,在这个代码只有一个标志,但一旦我弄明白的想法是,我会增加额外的宏变量和标志。以下是错误消息我得到:

8048 , CASE WHEN (PROCEDURE= &Px1.) THEN 1 ELSE 0 END AS CPT_+&Px1. 
                  - 
                  78 
ERROR 78-322: Expecting a ','. 

看来,问题的原因与字符串CPT_与宏变量组合。正如我所提到的,我尝试了几种方法来解决这个问题,但都没有成功。

在此先感谢您的帮助。

回答

0

这样的事情通常需要动态sql(尽管我不确定这对SAS有什么用,我相信它可能取决于你如何建立与数据库的连接)。

Proc sql; 

DECLARE @px1 varchar(20) = '12345' 
     ,@sql varhcar(max) = 
       'SELECT b.MEMBERID 
        , b.ENROL_MN 
        , CASE WHEN (a.PROCEDURE = ' + @Px1 + ') THEN 1 ELSE 0 
            END AS CPT_' + @px1 + ' 
        , a.DX1 
        , a.DX2 
        , a.DX3 
        , a.DX4 

        FROM ENROLLMENT as b 
        left join CLAIMS as a 
        on a.MEMBERID = b.MEMBERID' 

EXEC sp_excutesql @sql; 



QUIT; 
+0

这是TSQL不是SAS的实现,所以这个不相关的。 SAS完全不同。 – Joe

0

这里的问题是宏变量中的引号。

%let Px1='12345'; 

所以现在SAS是看到这一点:

... THEN 1 ELSE 0 END AS CPT_+'12345' 

这不是远程合法的!您需要删除'

%let Px1 = 12345; 

然后重新放在正确的位置。

CASE WHEN a.procedure = "&px1." THEN 1 ELSE 0 END AS CPT_&px1. 

注意"'为让宏变量的决心。

+0

我还会注意到,我不觉得这是一个非常好的方式去完成所述的任务:根据具体的细节,有许多比'SQL'更好的方法。 – Joe

+0

太棒了,乔。这个伎俩。感谢您的帮助。我愿意接受任何关于更好的方式去做这件事的建议。 – BillW

+0

@BillW汤姆的建议是一个开始,但我认为它太依赖于你想要做的事情。 PROC TRANSPOSE,一些建模过程或数据步骤可能是一个更好的解决方案,具体取决于你在做什么。 SQL并没有真正围绕这类任务进行优化,使用SAS的主要好处之一是你有很多已经建好的方法来做这样的事情,你不必亲自去做。 – Joe

0

如果您有一个列表,它可能有助于将列表放入表中。然后,您可以使用SAS代码生成代码来生成标志变量而不是宏代码。

说一个PX代码变量表。

data pxlist; 
    input px $10. ; 
cards; 
12345 
4567 
; 

然后,您可以使用PROC SQL查询来生成代码,使标志变量变成宏变量。

proc sql noprint; 
select catx(' ','PROCEDURE=',quote(trim(px)),'as',cats('CPT_',px)) 
    into :flags separated by ',' 
    from pxlist 
; 
%put &=flags; 
quit; 

代码看起来像

PROCEDURE= "12345" as CPT_12345,PROCEDURE= "4567" as CPT_4567 

因此,如果我们做出一些假数据。

data enrollment ; 
    length memberid $8 enrol_mn $6 ; 
    input memberid enrol_nm; 
cards; 
1 201612 
; 
data claims; 
    length memberid $8 procedure $10 dx1-dx4 $10 ; 
    input memberid--dx4 ; 
cards; 
1 12345 1 2 . . . 
1 345 1 2 3 . . 
; 

然后我们可以组合这两个表并创建标志变量。

proc sql noprint; 
create table want as 
    select *,&flags 
    from ENROLLMENT 
    natural join CLAIMS 
; 
quit; 

结果

memberid procedure dx1 dx2 dx3 dx4 enrol_mn CPT_12345 CPT_4567 
1  12345  1 2   201612 1   0 
1  345  1 2 3  201612 0   0 
+0

这太棒了,谢谢汤姆! – BillW