0

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

请注意 casenum 和 code 是字符变量,data 是数字变量

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

casenum 代码数据

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,并运行这些相同的测试那个casenum。

请记住,该数据集包含数十万个观察值。

4

3 回答 3

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;

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

于 2009-05-11T12:05:58.590 回答
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 = 最终输出。

让我们知道这个表达式是否出于某种原因需要是动态的。这应该可以轻松扩展到您提到的数据量,而不会出现任何问题。可以想象,您也可以在一次数据传递中使用散列来做同样的事情。

于 2009-05-12T02:06:57.967 回答
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 ;

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

于 2009-05-11T15:08:45.110 回答