Sas 对字符列求和,直到达到计数

Sas 对字符列求和,直到达到计数,sas,Sas,我有一个类似这样的表,其中包含更多记录和注释: +------+---------------+------+---------------+------+---------------+------+ |id |note_1 |len_1 |note_2 |len_2 |note_3 |len_3 | +------+---------------+------+---------------+------+--------------

我有一个类似这样的表,其中包含更多记录和注释:

+------+---------------+------+---------------+------+---------------+------+
|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数据步骤中创建一个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

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

%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的东西,那真的没有意义。只要创建一个求和变量,每次求和时,都要加上它

记住字符变量的长度返回最后一个非空格字符的长度,因此这准确地反映了您要查找的内容


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

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

%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的东西,那真的没有意义。只要创建一个求和变量,每次求和时,都要加上它

记住字符变量的长度返回最后一个非空格字符的长度,因此这准确地反映了您要查找的内容


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

规定的实际最大长度为32767,这也是SAS字符变量的最大长度。因此,如果结果超过32K个字符,您可能需要对所需变量的串联进行BLI,并允许正常截断

健壮的代码将使用一个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;
未指定长度时,数据步编译器将选择创建长度为$200的变量。从帮助文件:

返回变量的长度在数据步骤中,如果CATS函数向之前未分配长度的变量返回值,则该变量的长度为200字节。此外,如果串联运算符| |向之前未指定长度的变量返回一个值,则该变量将获得一个长度,该长度是所串联值的长度之和


声明的实际最大长度为32767,这也是SAS字符变量的最大长度。因此,如果结果超过32K个字符,您可能需要对所需变量的串联进行BLI,并允许正常截断

健壮的代码将使用一个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;
未指定长度时,数据步编译器将选择创建长度为$200的变量。从帮助文件:

返回变量的长度在数据步骤中,如果CATS函数向之前未分配长度的变量返回值,则该变量的长度为200字节。此外,如果串联运算符| |向之前未指定长度的变量返回一个值,则该变量将获得一个长度,该长度是所串联值的长度之和


为什么要使用vvaluex?请注意,SAS只会自动截断该值。你是在试图避免日志中的注释吗?@Tom最初也让我感到困惑——注意,他们使用它间接访问变量,不过,是以类似数组的方式,而不是实际编码数组。我不知道他们为什么要避开数组,但是,谁知道呢……我最初使用CATX来组合变量,但是SAS会在日志中显示一条警告,结果会完全为空。只使用vvaluex,因为我是SAS的新手,不确定在循环中引用列的最佳方式。警告:在调用CATX函数时,为结果分配的缓冲区不够长…正确的结果将包含35942个字符,但实际结果可能会被截断。。。或者完全为空,具体取决于调用环境。如果中间音符会让你超过极限,而后续音符则不会,那该怎么办?连接应该在“突破限制”测试结束吗?为什么要使用vvaluex?请注意,SAS只会自动截断该值。“你是想避开日志中的注释吗?”汤姆起初也让我感到困惑——注意
不过,目前他们正在使用它以类似数组的方式间接访问变量,而不实际编码数组。我不知道他们为什么要避开数组,但是,谁知道呢……我最初使用CATX来组合变量,但是SAS会在日志中显示一条警告,结果会完全为空。只使用vvaluex,因为我是SAS的新手,不确定在循环中引用列的最佳方式。警告:在调用CATX函数时,为结果分配的缓冲区不够长…正确的结果将包含35942个字符,但实际结果可能会被截断。。。或者完全为空,具体取决于调用环境。如果中间音符会让你超过极限,而后续音符则不会,那该怎么办?连接是否应该在“打破限制”测试中结束?最初发布了关于包括最后一个注释的一部分的评论。你的编辑修复了它。谢谢最初发表了关于包括最后一个注释的一部分的评论。你的编辑修复了它。谢谢