首页 > 解决方案 > 如何在 SAS 中编写 foreach 循环语句?

问题描述

我作为新手在 SAS 工作。我有两个数据集:

数据集1

唯一身份 A栏
1 15
1 39
2 20
3 10

数据集2

唯一身份 B栏
1 40
2 55
2 10

对于每个 UniqueID,我想用 ColumnA 的每个值减去 ColumnB 的所有值。我想创建一个随时为 1 的 NewColumn 1>ColumnB-Column >30。对于数据集 1 的第一行,其中 UniqueID = 1,我希望 SAS 遍历数据集 2 中也具有唯一 ID = 1 的所有行,并确定数据集 2 中是否存在列 B 和列 A 之间的差异的行大于 1 或小于 30。对于 Dataset 1 的第一行,应为 NewColumn 分配值 1,因为 40 - 15 = 25。对于 Dataset 1 的第二行,应为 NewColumn 分配值 0,因为 40 - 39 = 1(不大于 1)。对于数据集 1 的第三行,我再次希望 SAS 遍历数据集 2 中与数据集 1 中具有相同 UniqueID 的每一行 ColumnB,

所以我希望我的输出是:

唯一身份 A栏 新列
1 15 1
1 30 0
2 20 1

我尝试将 Dataset1 和 Dataset2 连接成一个 FullDataset。然后我尝试使用 do 循环语句,但我不知道如何为 UniqueID 的每个值执行循环。我尝试使用 BY 但这当然会产生错误,因为它仅用于增量。

DATA FullDataset;
    set Dataset1 Dataset2; /*Concatenate datasets*/
        do i=ColumnB-ColumnA by UniqueID;
            if 1<ColumnB-ColumnA<30 then NewColumn=1;
         output;
        end;
    RUN;

我知道我可能很遥远,但任何帮助将不胜感激。谢谢!

标签: sas

解决方案


因此,最直接回答您问题的方式是键控集。这不一定是我这样做的方式,但它很容易理解(与我使用的哈希表或 SQL 连接相反,可能是大多数人会使用的)。这正是你所说的:抓取一行A,为每个匹配的行B检查一个条件。它需要在数据集上有一个索引(嗯,至少在B数据集上)。

data colA(index=(id));
input ID ColumnA;
datalines;
1 15
1 39
2 20
3 10
;;;;

data colB(index=(id));
input ID    ColumnB;
datalines;
1 40
2 55
2 30
;;;;
run; 

data want;
  *base: the colA dataset - you want to iterate through that once per row;
  set colA;
  
  *now, loop while the check variable shows 0 (match found);
  do while (_iorc_ = 0);
    *bring in other dataset using ID as key;
    set colB key=ID ;
    * check to see if it matches your requirement, and also only check when _IORC_ is 0;
    if _IORC_ eq 0 and 1 lt ColumnB-ColumnA lt 30 then result=1;
    * This is just to show you what is going on, can remove;
    put _all_;
  end;
  
  *reset things for next pass;
  _ERROR_=0;
  _IORC_=0;
  
run;
  

推荐阅读