SAS:ID变量基于多种条件

SAS:ID变量基于多种条件,sas,Sas,我有以下数据集: ID Status 1 cake 1 cake 1 flower 2 flower 2 flower 3 cake 3 flower 4 cake 4 cake 4 cake 基本上,我只对按ID分组的观察结果感兴趣,这些观察结果至少包括一朵花。此外,我还想指出,按ID分组的观察结果是否只有花,或者它是否也是蛋糕。例如,理想情况下,我想要:

我有以下数据集:

ID      Status   
1       cake
1       cake
1       flower
2       flower
2       flower
3       cake
3       flower
4       cake
4       cake
4       cake
基本上,我只对按ID分组的观察结果感兴趣,这些观察结果至少包括一朵花。此外,我还想指出,按ID分组的观察结果是否只有花,或者它是否也是蛋糕。例如,理想情况下,我想要:

ID      Status      Indicator
1       cake        1
1       cake        1
1       flower      1
2       flower      2
2       flower      2
3       cake        1
3       flower      1
4       cake        0
4       cake        0
4       cake        0

我曾尝试以多种方式对数据集进行子集划分,并根据ID将其合并在一起,但它似乎不起作用

proc sql
浮现在脑海中:

proc sql;
    select t.*, tt.indicator
    from t join
         (select id, sum(case when status = 'flower' then 1 else 0 end) as indicator
          from t
          group by id
         ) tt
         on tt.id = t.id;
proc-sql
还对sql进行了“重新合并”扩展。这允许您执行以下操作:

proc sql;
    select t.*, tt.indicator,
           sum(case when status = 'flower' then 1 else 0 end) as indicator
    from t j
    group by id;

proc-sql
浮现在脑海中:

proc sql;
    select t.*, tt.indicator
    from t join
         (select id, sum(case when status = 'flower' then 1 else 0 end) as indicator
          from t
          group by id
         ) tt
         on tt.id = t.id;
proc-sql
还对sql进行了“重新合并”扩展。这允许您执行以下操作:

proc sql;
    select t.*, tt.indicator,
           sum(case when status = 'flower' then 1 else 0 end) as indicator
    from t j
    group by id;

这个基于输入的SAS数据步骤(我在这里称为test)将按ID组返回该指示符值

proc sort data=test;
by ID descending status;
run;

data result(drop=status);
set test;
by ID;
retain indicator;
if first.ID then indicator=0;
if status='flower' and indicator=0 then indicator=2;
if status='cake' and indicator=2 then indicator=1;
if last.ID then output;
run;
您可以将该结果与源数据连接起来,以获得您在文章中提供的结果

注:我没有足够的声誉对Gordon Linoff提供的答案发表评论,但我只想指出,该指标不会采用三个值(
0='no flower'
1='cake+flower'
2='only flower'
),而是每个ID的“flower”条目数,我不认为这是海报所要求的

按以下方式重写将给出预期结果,其指标值为
0='no flower'
1='only flower'
2='cake+flower'

proc sql;
  select t.*,
         (count(distinct status))*(sum(case when status = 'flower' then 1 else 0 end)>0) as indicator
  from test t
  group by id;
;
quit;

这个基于输入的SAS数据步骤(我在这里称为test)将按ID组返回该指示符值

proc sort data=test;
by ID descending status;
run;

data result(drop=status);
set test;
by ID;
retain indicator;
if first.ID then indicator=0;
if status='flower' and indicator=0 then indicator=2;
if status='cake' and indicator=2 then indicator=1;
if last.ID then output;
run;
您可以将该结果与源数据连接起来,以获得您在文章中提供的结果

注:我没有足够的声誉对Gordon Linoff提供的答案发表评论,但我只想指出,该指标不会采用三个值(
0='no flower'
1='cake+flower'
2='only flower'
),而是每个ID的“flower”条目数,我不认为这是海报所要求的

按以下方式重写将给出预期结果,其指标值为
0='no flower'
1='only flower'
2='cake+flower'

proc sql;
  select t.*,
         (count(distinct status))*(sum(case when status = 'flower' then 1 else 0 end)>0) as indicator
  from test t
  group by id;
;
quit;

如果您的数据已经按ID排序,那么您可以使用双道循环。第一个循环将检查是否存在这些值。然后可以使用另一个循环回写该组的所有详细信息行

data want ;
  do until (last.id);
    set have;
    by id;
    if status='flower' then _flower=1;
    else if status='cake' then _cake=1;
  end;
  if _flower and _cake then indicator=1;
  else if _flower then indicator=2;
  else indicator=0;
  do until (last.id);
    set have;
    by id;
    output;
  end;
run;

假设数据已经排序,这应该很快。

如果数据已经按ID排序,则可以使用双道循环。第一个循环将检查是否存在这些值。然后可以使用另一个循环回写该组的所有详细信息行

data want ;
  do until (last.id);
    set have;
    by id;
    if status='flower' then _flower=1;
    else if status='cake' then _cake=1;
  end;
  if _flower and _cake then indicator=1;
  else if _flower then indicator=2;
  else indicator=0;
  do until (last.id);
    set have;
    by id;
    output;
  end;
run;

假设数据已经排序,这应该很快。

请包括您的代码,您尝试了什么?请包括您的代码,您尝试了什么?我在前面做了类似的操作,但问题是它只在last.id=1时给指示器变量一个值,因此,其余的观察值为0,尽管它们应归类为1或2。@Karen Larsen,如我所述,将此结果与源表结合,将得到您在原始帖子中列出的结果。否则,我添加了一个带有Gordon Linoff答案“更正”版本的编辑(其中指标值1和2的含义与您发布的内容进行了交换)。非常感谢!我现在正在运行代码,但我的计算机似乎有问题,这可能与包含250万的数据集有关。观察。你知道需要更少计算机的代码吗?@KarenLarsen我个人通过运行“数据步”解决方案并加入源代码,比运行“proc-sql”解决方案获得更好的性能;但它们在我本地的机器上都非常有效。如果您正在运行SQL解决方案,您可能希望在查询的开头添加一个
create table
语句,因为SAS会创建一个报告输出,这比创建一个表输出花费的时间要长得多。我在前面做了类似的事情,但问题是,如果last.id=1,它只给指示符变量一个值,所以其余的观察值都是0,尽管它们应该被分类为1或2。@Karen Larsen如我所述,将此结果与源表结合,将得到您在原始帖子中列出的结果。否则,我添加了一个带有Gordon Linoff答案“更正”版本的编辑(其中指标值1和2的含义与您发布的内容进行了交换)。非常感谢!我现在正在运行代码,但我的计算机似乎有问题,这可能与包含250万的数据集有关。观察。你知道需要更少计算机的代码吗?@KarenLarsen我个人通过运行“数据步”解决方案并加入源代码,比运行“proc-sql”解决方案获得更好的性能;但它们在我本地的机器上都非常有效。如果您正在运行SQL解决方案,您可能希望在查询的开头添加一个
create table
语句,否则SAS会创建一个报告输出,这比创建一个表输出要长得多。