我有一个具有一个连接文本字段的数据集。我试图将其分解为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;
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;
答案 0 :(得分:4)
获取包含多分隔符的单词的另一种不同方法是使用call scan
。它将告诉你第n个单词的位置(以及我们忽略的长度)(并且可以向前或向后,这样你就可以在字符串的中间进行搜索)。
对于这个特殊情况实施它非常简单:
position
length
和call scan
是/mnt/usr/lib
填充了我们可以使用的值的变量。 (我们也可以用这种方式完成日期和陈述,但这比使用函数要多得多。)
答案 1 :(得分:2)
正则表达式可能是一个选项
我建议你从这篇论文开始:http://www2.sas.com/proceedings/sugi29/265-29.pdf
如果您从未接触过这些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函数启动的表达式将给出提取您感兴趣的字符串的起点。 Length + Cats函数将给出日期和状态的总长度,+ 3是偏移' - '。
答案 2 :(得分:1)
_INFILE_ Magic
是此搜索词。基本上,我们使用_infile_
自动变量(包含当前从输入文件中读入的行)来利用简单的输入语法。
*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.;
请注意,这仅适用,因为您的嵌入分隔符出现在行尾。如果它们位于行的中间,这种方法将无法工作,您将不得不使用不同的方法(例如正则表达式,或告诉任何人给你一个以这种方式格式化的文件,以便更多地给你有用的方式,即不使用也在数据中的分隔符。
答案 3 :(得分:1)
使用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;