将单个观察分成多个观察结果

时间:2014-03-26 13:33:50

标签: sas

我有以下SAS数据集:

data mydata;
   LENGTH id 4.0 num 4.0 A $ 4. B $ 8. C $ 20.;
   input id num A $ B $ C $;
   datalines;
1 1 x yy zzzzz
2 1 x yy zzzzz
3 2 xq yyqq zzzzzqqqqq
4 1 x yy zzzzz
5 3 xqw yyqqww zzzzzqqqqqwwwww
6 1 x yy zzzzz
7 4 xqwe yyqqwwee zzzzzqqqqqwwwwweeeee
;

看起来像

mydata
-------------------
id num A B C
1  1   x yy zzzzz
2  1   x yy zzzzz
3  2   xq yyqq zzzzzqqqqq
4  1   x yy zzzzz
5  3   xqw yyqqww zzzzzqqqqqwwwww
6  1   x yy zzzzz
7  4   xqwe yyqqwwee zzzzzqqqqqwwwwweeeee

问题在于每个观察数量为num> 1实际上包含多个"观察的数据"我想在SAS中使用一些逻辑将其拆分。这是我想要得到的一个例子:

mydatawanted
-------------------
id num A B C
1  1   x yy zzzzz
2  1   x yy zzzzz
3  1   x yy zzzzz
3  1   q qq qqqqq
4  1   x yy zzzzz
5  1   x yy zzzzz
5  1   q qq qqqqq
5  1   w ww wwwww
6  1   x yy zzzzz
7  1   x yy zzzzz
7  1   q qq qqqqq
7  1   w ww wwwww
7  1   e ee eeeee

基本上,如果num> 1我想根据每个项目的长度取每个变量的子串,然后将这些子项输出为num = 1的新观察值。这是我到目前为止尝试编码的内容:

data mydata2(drop=i _:);
    set mydata; /*use the data from the original data set */
    _temp_id = id; /*create temp variables from the currently read observation */
    _temp_num = num;
    _temp_A = A;
    _temp_B = B;
    _temp_C = C;
    if (_temp_num > 1) THEN /* if num in current record > 1 then split them up */
        do i = 1 to _temp_num;
            id = _temp_id; /* keep id the same */
            num = 1; /* set num to 1 for each new observation */
            A = substr(_temp_A,i,i); /*split the string by 1s */
            B = substr(_temp_B,1 + 2 * (i - 1),i * 2); /*split the string by 2s */
            C = substr(_temp_C,1 + 5 * (i - 1),i * 5); /*split the string by 5s */
            OUTPUT; /* output this new observation with the changes */
        end;
    else OUTPUT; /* if num == 1 then output without any changes */
run;

然而,它并没有像我想要的那样工作(我提出了一些评论来说明我认为每一步都发生了什么)。它实际上产生以下结果:

mydata2
-------------------
id num A B C
1  1   x yy zzzzz
2  1   x yy zzzzz
3  1   x yy zzzzz
3  1   q qq qqqqq
4  1   x yy zzzzz
5  1   x yy zzzzz
5  1   qw qqww qqqqqwwwww
5  1   w ww wwwww
6  1   x yy zzzzz
7  1   x yy zzzzz
7  1   qw qqww qqqqqwwwww
7  1   we wwee wwwwweeeee
7  1   e ee eeeee

此mydata2结果与mydatawanted相同。 num = 1的行很好但是当num> 1时1输出记录与我想要的大不相同。但记录总数是正确的。我不确定发生了什么,因为这是我第一次尝试这样复杂的SAS逻辑,但我很感激在修复我的代码或使用任何替代方法完成我想做的任何帮助。谢谢!

编辑:我修复了原始输入mydata数据语句的问题并更新了问题。

1 个答案:

答案 0 :(得分:1)

您的子字符串不正确。 Substr接受参数(original string, start, length),而不是(original string, start, ending position)。因此length应为1,2,5而不是i,i*2,i*5

        A = substr(_temp_A,i,1); /*split the string by 1s */
        B = substr(_temp_B,1 + 2 * (i - 1),2); /*split the string by 2s */
        C = substr(_temp_C,1 + 5 * (i - 1),5); /*split the string by 5s */