SAS:提取ID';从文本字符串中用破折号分隔的
我有一个数据集,它有一个连接的文本字段。我试图在SAS 9.4中将其分为三个文本列SAS:提取ID';从文本字符串中用破折号分隔的,sas,delimiter,Sas,Delimiter,我有一个数据集,它有一个连接的文本字段。我试图在SAS 9.4中将其分为三个文本列 Obs Var1 1 MAY12-KANSAS-ABCD6194-XY7199-BRULE 2 JAN32-OHIO-BZ5752-GARY 观察结果1的输出应如下所示: Obs Date State ID 1 MAY12 KANSAS ABCD6194-XY7199-BRULE 这是我所拥有的,适用于日期和州。但是,我无法让第三部分(ID)忽略分隔符: data have;
Obs Var1
1 MAY12-KANSAS-ABCD6194-XY7199-BRULE
2 JAN32-OHIO-BZ5752-GARY
观察结果1的输出应如下所示:
Obs Date State ID
1 MAY12 KANSAS ABCD6194-XY7199-BRULE
这是我所拥有的,适用于日期和州。但是,我无法让第三部分(ID)忽略分隔符:
data have;
input Var1 &$64.;
cards;
MAY12-KANSAS-ABCD6194-XY7199-BRULE
JAN32-OHIO-BZ5752-GARY
;
run;
data need;
length id $16;
set have;
date = scan(var1,1,'-','o');
state = scan(var1,2,'-','o');
id = scan(var1,3,'-','');
run;
正则表达式可能是一个选项 详细文档可在此处找到: 我建议你从这篇论文开始: 如果您从未接触过那些PRX函数,那么对代码的直接解释可能会让您更加困惑
data have;
input Var1 &$64.;
cards;
MAY12-KANSAS-ABCD6194-XY7199-BRULE
JAN32-OHIO-BZ5752-GARY
;
run;
data want;
set have;
date=scan(var1,1);
state=scan(var1,2);
id=prxchange('s/^\w+-\w+-//',1,var1);
run;
或者作为对现有代码的简单修复:
data want;
set have;
date=scan(var1,1);
state=scan(var1,2);
/* id=prxchange('s/^\w+-\w+-//',1,var1);*/
id=substr(var1,length(cats(date,state))+3);
run;
由length函数启动的表达式将给出提取感兴趣字符串的起点。长度+Cats函数将给出日期和状态的总长度,+3是偏移量“-”
\u infle\umagic
是此项的搜索词。基本上,我们使用\u infle\u
自动变量(包含当前从输入文件读入的行)来利用简单的语法进行输入
*Create a dataset with your data;
data have;
length var1 $100;
input var1 $;
datalines;
MAY12-KANSAS-ABCD6194-XY7199-BRULE
JAN32-OHIO-BZ5752-GARY
;;;;
run;
data want;
infile cards dlm='-'; *cards=datalines=in-line data, just used to get something blank to pretend to read from;
length
date $5
state $20
id $50
; *set up lengths for your variables;
set have; *Now read in your dataset;
input @1 @@; *Start the input pointer at the beginning of the imaginary line and do not advance lines ever (since we have no lines!);
_infile_=var1; *Assign the contents of var1 to _infile_, so now we have a line;
input
date $
state $
id $ & @@
; *Input using normal input techniques. & tells it to read the rest of that line into the id variable (even the dashes), and @@ says stay on this line still (since we have more rows).
cards;
run; *Note we do not really have any cards/datalines.;
注意,这只适用于嵌入的分隔符出现在行的末尾。如果他们在中间,这个方法就不起作用了,你必须使用一种不同的方法(比如正则表达式),或者告诉任何人给你一个以这种方式格式化的文件,以更有用的方式给你,即不使用数据中的定界符。.获取包含单词的多分隔符的另一种不同方法是使用。它将告诉你第n个单词的位置(和长度,我们忽略它)(可以向前或向后,这样可以给你一些在字符串中间搜索的能力)。 针对这种特殊情况实施,非常简单:
data want;
set have;
length
date $5
state $20
id $50
;
date = scan(var1,1);
state= scan(var1,2);
call scan(var1,3,position,length);
id = substr(var1,position);
run;
位置
和长度
是调用扫描
填充值的变量,我们可以使用这些值。(我们也可以这样做日期和状态,但这比使用函数要复杂。)使用tranwrd删除日期和状态
data want;
set have;
length
date $5
state $20
id $50
;
date = scan(var1,1);
state= scan(var1,2);
id= tranwrd(var1,cats(date,'-',state,'-'),'');
run;
谢谢你的帮助。我不熟悉PRXCHANGE函数,所以在代码中很难操作它。您建议的代码是“ABCD6194-XY7199-”而不是“ABCD6194-XY7199-BRULE”。我将如何修改函数以获得字符串的最后一个“BRULE”片段?@Haikoubian您可能需要解释正则表达式中的逻辑,即解释它正在搜索的模式,以帮助Ryan了解它是如何工作的。这可能是一个长度问题。在数据步骤的开头添加一个长度语句:data-want;集有;长度id$100/*大到足以容纳尽可能长的ID*/@Haikoubian StackOverflow更喜欢“教人钓鱼”的方法-请始终解释您的代码在做什么以及该方法是什么,甚至优先于提供任何代码。@Haikoubian感谢您添加这一点。请为第一部分添加直接解释-一些简单的东西就足够了,比如“这里我们用PRX删除前两部分,其余部分是ID”。链接到函数文档比简单地解释你正在做的事情背后的原因更重要。你在第二段中所做的是完美的(虽然我不会像那样使用斜体字,但读起来有点难)。