如何在SAS中使用嵌套的DO循环,而我的索引在1处重新启动

时间:2014-11-24 20:50:58

标签: sas

我正在尝试在SAS中编写一个数据步骤,以便以后使用proc rank,创建六个组(组变量),每个组八个主题(主题变量),每个主题分配一个随机数(队列)变量,稍后在proc rank中使用)。这是非常简单的除了我希望我的主题编号为1-48,同时仍然分成六组(A,B,C等)。只是编写一个嵌套的do循环对于包含主题1到主题8的组A,B等都是可以的,但是我希望主题A具有1-8,B具有9-16,依此类推。现在,我有以下代码来执行此操作:

data treatment;
do group = 'A', 'B', 'C', 'D', 'E', 'F';

    if group = 'A' then do subject = 1 to 8;
        cohort = ranuni(1234);
    output;
    end;

    else if group = 'B' then do subject = 9 to 16;
        cohort = ranuni(1234);
        output;
    end;

    else if group = 'C' then do subject = 17 to 24;
        cohort = ranuni(1234);
        output;
    end;

    else if group = 'D' then do subject = 25 to 32;
        cohort = ranuni(1234);
        output;
    end;

    else if group = 'E' then do subject = 33 to 40;
        cohort = ranuni(1234);
        output;
    end;

    else if group = 'F' then do subject = 41 to 48;
        cohort = ranuni(1234);
        output;
    end;

end;
run;

这确实有效,但一团糟。有没有办法让#34;主题" A组的索引从1到8,B组的索引从9到16,依此类推,没有所有的条件?我想在SAS中有其他工具(宏?proc sql?),它们更容易使用,但我现在只限于在数据步骤中做循环。

免责声明:这是一年级SAS课程的家庭作业。我的代码工作正常,我现在正在做我需要做的事情(如果我能解决其他问题,我会按原样提交它),但我知道它的效率非常低,我似乎找不到任何关于如何摆脱所有这些if-else语句的东西。 (我可能不知道要搜索什么 - 我已经阅读了几个关于使用嵌套do循环的页面,但似乎没有什么能帮助解决我的问题。这里的所有内容似乎都与循环有关在宏中,我还没有。)

我不希望我的代码完全重写 - 它的作业,我需要自己做! - 但我会欣赏正确方向的任何指针,即使它们只是搜索条件。在这一点上,我完全坚持我需要查看的内容。

1 个答案:

答案 0 :(得分:3)

正如您所料,有一百五十种方法可以解决SAS中的这个问题。

所以我假设您想要一个

的数据集
A 1
A 2
A 3
A 4
A 5
A 6
A 7
A 8
B 9
B 10
B 11
...
F 48

之后加上一些随机的片段。我这样做的方法是分别计算这些部分。

你实际上有一个循环,1到48,其中A-F分组有效地应用于循环,对吗?所以你应该尝试以这种方式构建它:

data want;
  set have;
  do subject = 1 to 48;
    group=<logic to determine group>;
    cohort=<logic to determine cohort>;
    output;
  end;
run;

有几种不同的方法<logic to determine group>;最糟糕的&#39; way是一系列if语句,即:

if subject le 8 then group='A';
else if subject le 16 then group='B';
...
else group='F';

在没有条件逻辑的单个语句中,我可以看到几个很好的选项来确定它。如果你想自己解决这个问题,那就去做吧;如果你想要一个提示或解释,请发表评论,我很乐意解释我是如何做到的,但我认为现在最好不要说明(特别是因为确切的方法可能取决于关于你迄今为止所学到的知识。


第二种选择是根本不为你的主题使用循环,而是使用计数器。

do class='A','B',...;
  subjID+1;
  cohort=...;    
end;

这基本上就是你如何保持循环的外部&#39;计数器;它本身并不是一个真正的编程循环,但它允许您跟踪ID。这是你常常在其他地方看到的东西,可能是你的导师所得到的。在您的特定示例中,我更喜欢单循环1:48解决方案,因为它避免了相当多的字母硬编码,但这也是一种常见的解决方案。


一方面注意:我强烈建议不要学习ranuni,而是学习使用rand功能。 ranuni基于劣质PRNG; rand是严格优越的,并且还具有额外优势,即您不必无用地重复种子(因为种子在第一次通话后实际上没有任何效果!)。如果您的老师已指示您使用ranuni,我建议您同时学习这两项内容,并且仅在提交回课堂的家庭作业中包含ranuni。如果您的老师有兴趣了解原因,Rick Wicklin有一个很好的解释here


如果真的像双循环一样,有两种循环可以做到这一点 - 但它需要与上述1:48循环相同的基本概念。 (如果您想完全解决第一个问题,请不要进一步阅读。)要阅读剧透,请点击“改进”。或者&#39;编辑&#39;在这个答案上,我把它隐藏在角撑中(为什么没有扰流标签......)