【问题标题】:SAS - Do loop within If statement?SAS - 在 If 语句中循环吗?
【发布时间】:2012-11-19 01:51:13
【问题描述】:

我断断续续地使用 SAS 一年了,我终于开始研究数组、宏和所有很酷的东西了。

我想做什么:

我有一个合并的数据集,其中包含来自不同年级学生的测试数据。我需要为每个年级创建不同的文件。我没有等级变量来轻松对数据集进行排序并创建不同的文件。我确实有一个特定于每个年级的变量索引。

示例 - 我有什么:

+-------+--------+--------+--------+--------+--------+
|  ID   | sc_132 | sc_139 | sc_142 | sc_143 | sc_151 |
+-------+--------+--------+--------+--------+--------+
| 16623 | 1      | 1      | 0      | .      | .      |
| 16624 | 1      | 0      | 0      | .      | .      |
| 16626 | 1      | 1      | 1      | .      | .      |
| 17221 | .      | .      | .      | 1      | 0      |
| 17222 | .      | .      | .      | 0      | 1      |
| 17225 | .      | .      | .      | 0      | .      |
+-------+--------+--------+--------+--------+--------+

示例 - 我想要什么:

+-------+--------+--------+--------+--------+--------+
|  ID   | sc_132 | sc_139 | sc_142 | sc_143 | sc_151 |
+-------+--------+--------+--------+--------+--------+
| 16623 | 1      | 1      | 0      | .      | .      |
| 16624 | 1      | 0      | 0      | .      | .      |
| 16626 | 1      | 1      | 1      | .      | .      |
+-------+--------+--------+--------+--------+--------+
+-------+--------+--------+--------+--------+--------+
|  ID   | sc_132 | sc_139 | sc_142 | sc_143 | sc_151 |
+-------+--------+--------+--------+--------+--------+
| 17221 | .      | .      | .      | 1      | 0      |
| 17222 | .      | .      | .      | 0      | 1      |
| 17225 | .      | .      | .      | 0      | .      |
+-------+--------+--------+--------+--------+--------+

我在哪里:

我有很多特定于每个年级的变量,其中一些变量包含缺失的数据,所以为了彻底,我应该检查所有特定于年级的变量,并输出包含任何这些字段中数据的任何观察结果。我可以使用非常长的 IF THEN 语句...

DATA grade1 grade2 grade3 grade4;
SET gradeall;
    IF sc_132 ^= . OR sc_139 ^= . OR (AND SO ON FOR ABOUT 34 VARIABLES) THEN OUTPUT grade1;
RUN;

但我认为这是使用数组的好时机。我找不到任何易于解析的关于何时何地可以使用 do 循环的文档。使用我对其他编程语言的逻辑以及我浏览过的有关 do 循环的内容,我整理了以下内容。

%let gr1_var = sc_132 sc_139 sc_142;
/*-GRADE SPECIFIC ARRAY REPEATED FOR OTHER GRADES -*/

DATA grade1 grade2 grade3 grade4;
SET gradeall;
PUT &gr1_var;
ARRAY grade1 [*] &gr1_var;
IF (
    DO i= 1 TO (DIM(items5_all)-1);
        items5_all(i) ^=. OR ;
    END;
    DO i= DIM(items5_all);
        items5_all(i) ^=.;
    END;
    )
THEN OUTPUT grade1;
    /*-IF THEN STATEMENT THEN REPEATED FOR OTHER GRADES-*/
run;

我希望这会给我相当于上面的长 IF THEN 语句而无需键入它。但它当然是没有功能的。

你甚至可以在 If 语句中使用 do 循环吗(我还没有找到任何这样的例子)?
有人对如何完成这项任务有任何建议吗?

【问题讨论】:

    标签: arrays sas do-loops


    【解决方案1】:

    我认为,如果您只想输出包含任何特定字段中数据的任何观察,您可以只做一个sum 的数组。如果任何观察值没有变量值,则总和为空,因此不会输出该观察值。不需要循环。就像:

     %let gr1_var = sc_132--sc_142; /*for array definition, you may use "--" or "-" */
     %let gr2_var = sc_143 sc_151;
    
     DATA grade1 grade2;
     SET gradeall;
     ARRAY grade1 [*] &gr1_var;
     ARRAY grade2 [*] &gr2_var;
     if sum(of grade1(*))^=. then output grade1;
     if sum(of grade2(*))^=. then output grade2;
     run;
    

    顺便说一下,如果这里使用宏,就不用写多个if..then和数组定义了。

    而且我不认为你可以在 if..else 语句中使用 DO LOOP,就像你放在这里的那样。

    【讨论】:

    • 谢谢!我知道我必须做一些相当简单的事情。当您的变量没有连续编号但属于设定范围时,您可以使用 -- 或 - 来定义一个数组吗?例如,在我上面使用的变量名称中,gr1_var 数组只有三个 sc_132--sc_142 中的值。如果我的数据集中没有 sc_133,这样定义还可以吗?
    • "--" 是关于位置的,而 '-' 是关于连续数字的。在这里,由于“sc_132 sc_139 sc_142”三列一起放在您的表中,“--”可以像“left_column--right_column”一样在这里使用以包括(仅)这三列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多