求和列的总和,直到达到计数

时间:2018-08-27 13:19:05

标签: sas

我有一个看起来像这样的表(带有更多记录和更多注释):

+------+---------------+------+---------------+------+---------------+------+
|id    |note_1         |len_1 |note_2         |len_2 |note_3         |len_3 |  
+------+---------------+------+---------------+------+---------------+------+
|10001 |"abcde"        |5     |"abc"          |3     |"abcdefg"      |7     |  
|10002 |"defghijk"     |8     |"ghuio"        |5     |"yuio"         |4     | 
|10003 |"abc"          |3     |"defg"         |4     |"qw"           |2     | 
+------+---------------+------+---------------+------+---------------+------+

,我想在SAS data步骤中创建一个do循环,该循环将所有音符连接起来直到达到一定长度(在此示例中为10)。这是为该示例创建的理想列,给定最大值为10:

+------+--------------+
|id    |concat_notes  |
+------+--------------+
|10001 |"abcdeabcab"  |
|10002 |"defghijkgh"  |
|10003 |"abcdefgqw"   |
+------+--------------+

这是我要创建的代码:

data length;
set notes;
concats = "";
do i=1 to 3;
    if (vvaluex(cats("len_",i)) > 10) then concat_notes= concats;
    else concats = cats(concats,vvaluex(cats("note_",i)));
end;
run;

注意:实际上,所有注释都非常长,我的最大长度为32767。由于空间问题,我无法将它们全部串联起来并使用substrn来获取前32767个注释。

2 个答案:

答案 0 :(得分:6)

声明的实际最大长度为32,767,这也是SAS字符变量的最大长度。因此,如果结果超过32K个字符,您可能希望对所需变量进行串联,并让普通截断发生。

严格的代码将使用length语句来指定为存储结果的变量分配多少空间。

set notes;
length notes_catted $32767;
notes_catted = cats (of note_:);

不强壮

set notes;
notes_catted = cats (of note_:);  * variable will be given implicit default length $200;

当未指定length时,DATA Step编译器将选择创建一个长度为$ 200的变量。从帮助文件中:

  

返回变量的长度

在DATA步骤中,如果CATS函数将一个值返回给以前未分配长度的变量,则该变量为给定200字节的长度。 另外(斜体字),如果串联运算符(||)向先前未分配长度的变量返回值,则该变量的长度即为长度之和连接的值中的一个。

答案 1 :(得分:2)

似乎您可以直接检查长度:

%let max_length=10;
data have;
input id note_1 $ len_1 note_2 $ len_2 note_3 $ len_3;
datalines;
  10001    abcde           5        abc             3        abcdefg         7         
  10002    defghijk        8        ghuio           5        yuio            4        
  10003    abc             3        defg            4        qw              2        
;;;;
run;
data want;
  set have;
  array notes note_:;
  length cat_note $10;
  do _i = 1 to dim(notes);
    if length(cat_note) + length(notes[_i]) le &max_length. then 
        cat_note = cats(cat_note,notes[_i]);
    else if length(cat_note) lt &max_length. then 
        cat_note = cats(cat_note, substr(notes[_i],1,(&max_length.-length(cat_note))));  *added to get last bit;
  end;
  keep id cat_note;
run;

如果出于某种原因您不想使用length函数来检查长度,也可以直接添加长度,但这在性能上似乎是不错的。那个vvaluex的东西,但这没有任何意义。只需创建一个求和变量,并在每次添加内容时将其添加即可。

记住字符变量的length()可以返回直到最后一个非空格字符的长度,因此这可以准确地反映您要查找的内容。

已编辑以将剩余部分添加到精确到10。