SAS:从文本字符串中用短划线分隔ID

时间:2015-06-10 13:28:09

标签: 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;
   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;

4 个答案:

答案 0 :(得分:4)

获取包含多分隔符的单词的另一种不同方法是使用call scan。它将告诉你第n个单词的位置(以及我们忽略的长度)(并且可以向前或向后,这样你就可以在字符串的中间进行搜索)。

对于这个特殊情况实施它非常简单:

position

lengthcall scan/mnt/usr/lib填充了我们可以使用的值的变量。 (我们也可以用这种方式完成日期和陈述,但这比使用函数要多得多。)

答案 1 :(得分:2)

正则表达式可能是一个选项

详细的文件可以在这里找到:http://support.sas.com/documentation/cdl/en/lefunctionsref/67398/HTML/default/viewer.htm#n0r8h2fa8djqf1n1cnenrvm573br.htm

我建议你从这篇论文开始: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;
相关问题