【问题标题】:How to count with condition in SAS如何在SAS中计算条件
【发布时间】:2014-04-03 15:19:23
【问题描述】:

我有一张表,其中包含从 1 到 11 的事件,变量有 3 种字符,如 HSP、REP、OH。我需要通过创建一个新列作为 OH1、OH2、OH3、OH4 来计算 HSP。每列的描述是

1) 第一个 OH 之前的 HSP 数
2) 第 1 和第 2 OH 之间的 HSP 数量
3) 第 2 和第 3 OH 之间的 HSP 数量
4) 第 3 和第 4 OH 之间的 HSP 数量

SLN     EV1 EV2 EV3 EV4 EV5 EV6 EV7 EV8 EV9 EV10 EV11
120132  HSP OH  HSP HSP REP OH  HSP HSP HSP OH  REP
120135  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP OH
120200  OH  HSP OH  HSP HSP OH  HSP OH  HSP OH  HSP
120251  OH  HSP 
120318  HSP OH  HSP HSP HSP OH  HSP HSP HSP HSP HSP
120327  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP HSP
120509  HSP OH  HSP HSP HSP HSP OH  HSP HSP OH  HSP
120510  HSP HSP     

如果根本没有后面的 'OH' 则设置为缺少 E.g.120327: oh1=0, oh2=4, oh3=。

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    这是一种使用数组而不做字符串连接和解析的方法

    data counts;
    input SLN EV1 $ EV2 $ EV3 $ EV4 $ EV5 $ EV6 $ EV7 $ EV8 $ EV9 $ EV10 $ EV11 $;
    array EV[11] ;
    array OH[4];
    
    next = 1;
    do i=1 to 4;
        oh[i] = 0;
    end;
    do i=1 to 11;
        if next > 4 then leave;
        if ev[i] = "HSP" then
            OH[next] = OH[next] + 1;
        else if ev[i] = "OH" then
            next = next + 1;
    end;
    
    datalines;
    120132  HSP OH  HSP HSP REP OH  HSP HSP HSP OH  REP
    120135  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP OH
    120200  OH  HSP OH  HSP HSP OH  HSP OH  HSP OH  HSP
    120251  OH  HSP REP HSP REP HSP HSP HSP HSP OH  HSP
    120318  HSP OH  HSP HSP HSP OH  HSP HSP HSP HSP HSP
    120327  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP HSP
    120509  HSP OH  HSP HSP HSP HSP OH  HSP HSP OH  HSP
    120510  HSP OH  HSP REP HSP HSP OH  HSP HSP HSP HSP
    ;
    run;
    

    【讨论】:

    • 很好的答案,我知道会有更好的方法!
    • 很好,但是如果SN只有一个带有HSP的事件EV1,它输出OH1为1,EV1和EV2有HSP HSP,EV3没有OH,那么它也输出为OH1为2。但我如果HSP后没有OH要输出,输出应该为null。
    • 要根据您的要求更新此版本需要更多的工作。将此 else if ev[i] = "OH" then 更改为 then do; 块并使用例如递增变量chk+1;。然后在do i=1 to 11; 块完成后,检查chk 值是否为零并将oh1-oh4 变量设置为缺失。我希望我已经解释过了,好吧,也许@DomPazz 有更好的方法......
    【解决方案2】:

    这应该可行:

    data want;
      set have;
      x1=cat(of ev1-ev11);
      x2=' '||tranwrd(x1,'OH','|');
      array oh oh1-oh4;
      if index(x2,'|') then
      do i = 1 to 4;
        oh[i]=count(scan(x2,i,'|'),'HSP');
      end;
      else call missing(of oh1-oh4);
      drop x1-x2 i;
    run;
    

    x1 将代码连接成一个长字符串。 x2 增加了管道,使得 oh 计算中的扫描功能成为可能,它还在前面添加了一个空格,如果第一个代码是 'OH',它还允许 oh1 等于零

    如果您需要将其扩展到 11 个 ev 列和 4 个 OH 计数之外,您可以使用数组或宏。

    编辑:为 OH 计数添加了数组。

    如果没有找到OH,则编辑为空值。

    修订

    data counts;
    input SLN EV1 $ EV2 $ EV3 $ EV4 $ EV5 $ EV6 $ EV7 $ EV8 $ EV9 $ EV10 $ EV11 $;
    array EV[11] ;
    array OH[4];
    chk=0;
    next = 1;
    do i=1 to 4;
        oh[i] = 0;
    end;
    do i=1 to 11;
        if next > 4 then leave;
        if ev[i] = "HSP" then
            OH[next] = OH[next] + 1;
        else if ev[i] = "OH" then do;
            next = next + 1;
                chk+1;
            end;
        end;
        if chk<4 then do j=chk+1 to 4;
          oh[j]=.;
        end;
    
    
    
    datalines;
    120132  HSP OH  HSP HSP REP OH  HSP HSP HSP OH  REP
    120135  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP OH
    120200  OH  HSP OH  HSP HSP OH  HSP OH  HSP OH  HSP
    120251  OH  HSP REP HSP REP HSP HSP HSP HSP OH  HSP
    120318  HSP OH  HSP HSP HSP OH  HSP HSP HSP HSP HSP
    120327  OH  HSP HSP HSP HSP OH  HSP HSP HSP HSP HSP
    120509  HSP OH  HSP HSP HSP HSP OH  HSP HSP OH  HSP
    120510  HSP OH  HSP REP HSP HSP OH  HSP HSP HSP HSP
    ;
    run;
    

    【讨论】:

    • 很好,但是如果SN只有一个带有HSP的事件EV1,它输出OH1为1,EV1和EV2有HSP HSP,EV3没有OH,那么它也输出为OH1为2。但我如果HSP后没有OH就想输出,输出应该为null
    • 修改后的版本现在检查是否有“OH”,然后进行计数。如果没有,则将所有 OH 计数变量设置为缺失。
    • 嗨,mjsqu,我使用了相同的代码,但无论条件如何,oh1-oh4 都会为空。
    • 对不起,索引应该包含'|'而不是'OH'
    • 对不起,它只在事件没有 OH 的情况下工作,但在 ev1:HSP、ev2:OH、ev3:HSP 的情况下,它在 ev2:OH 之后将 HSP 计数到 OH2 的输出中。如果有 HSP-OH-HSP 那么我想要输出 OH1=1, OH2=0, OH3=0, OH4=0。
    猜你喜欢
    • 2017-12-27
    • 1970-01-01
    • 2019-09-02
    • 2016-07-12
    • 2023-01-17
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多