SAS行比较和查询?或需要其他解决方案。我很难过

时间:2009-05-11 02:50:39

标签: sas

我的情况是,对于casenum的每个独特观察,我想在“casenum”的“代码”的各种观察之间运行不同的查询和算术运算(见下文)。例如,对于casenum 1234567,我想减去代码0200的数据 - 代码0234或531 - 53.请记住,此数据集中有数千个观察值。有没有简单的方法来执行此操作或与特定行进行行比较。

请注意,casenum和代码是字符变量,数据是数字变量

以下是数据集结构的示例:

casenum  code  data

1234567  0123  4597  
1234567  0234    53  
1234567  0100   789  
1234567  0200   531  
1234567  0300   354  
1111112  0123    79  
1111112  0234    78  
1111112  0100    77   
1111112  0200  7954  
1111112  0300    35

这是逻辑,虽然在语法上可能不正确我想要做的事情。

对于casenum相同的代码观察,在这些casenums中 如果数据代码0234 + 数据代码0100 - 数据代码0123 ne 数据代码0200然后newvariable ='YES'

换句话说,我想测试一下53 + 789 - 4597 ne 531.之后,在casenum 1234567中运行其他类似的测试,我希望它转移到下一个casenum,然后运行那些那个案例的相同测试。

请记住,此数据集中包含数十万个观察结果。

3 个答案:

答案 0 :(得分:1)

我不清楚你的逻辑对于代码的减法部分是什么,但是我可以建议选择一组行。乍一看,我会获得一个不同的casenum值列表。

proc sql;
select distinct casenum 
into :casenum_list separated by ' '
from dataset;
quit;

既然你有一个所有不同casenum值的列表,我会按照你需要的逻辑迭代这些行。

可能使用另一个proc sql,如:

%MACRO DOIT;
%LET COUNT=1;
%DO %UNTIL (%SCAN(&casenum_list,&COUNT) EQ);

%LET CASENUM_VAR=%SCAN(&casenum_list,&COUNT);

PROC SQL;
SELECT
<INSERT SOME SQL LOGIC HERE>
FROM 
DATASET
WHERE CASENUM=&CASENUM_VAR;
QUIT;

%LET COUNT=%EVAL(&COUNT+1);        

%MEND DOIT;

%DOIT;

我希望这会有所帮助。如果您可以更深入地了解要在行中完成的内容,我可以更具体。

答案 1 :(得分:1)

如果公式是固定的(正如您的示例所示),则不应该有任何理由不能进行简单的转置,然后明确声明测试。

/* Transpose the data by casenum */    
proc transpose data=so846572 out=transpose_ds;
    id  code;
    var data;
    by casenum;
run;

/* Now just explicitly write your conditional expression */  
data StackOverflow;
    set transpose_ds;

    if _0234 + _0100 - _0123 <> _0200 then newvariable="yes";
run;

其中so846572 =原始数据集,transpose_ds =转置版本,StackOverflow =最终输出。

如果这个表达式由于某种原因需要动态,请告诉我们。这应该很容易扩展到你提到的数据量没有任何问题。在数据的一次传递中,你可以想象用哈希做同样的事情。

答案 2 :(得分:0)

我认为我的问题没有足够的信息可以提供帮助,但我会把它扔掉...... 如果要进行行比较,还可以使用数据步骤。假设您的数据按casenum排序,您可以先使用。最后。确定何时有一个新的casenum以及当你在casenum的最后一行时。如果您想在行之间总结数据值,或者根据多次列出的casenum的前一行做出决策。

Data work.temp ;
 retain casenum_data ;

 set lib.data ;
 by casenum ;

 if first.casenum then do ;
   /* <reset hold vars> */
   casenum_data = 0 ;
 end ;

 if code = "0200" or code = "234" then .....


 if last.casenum then do ;
   /* output casenum summary */
   output ;
 end ;

run ;

发布有关需求的更多信息,可以提供更多帮助。