《SAS编程与数据挖掘商业案例》学习笔记之十九

前端之家收集整理的这篇文章主要介绍了《SAS编程与数据挖掘商业案例》学习笔记之十九前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

继续《SAS编程与数据挖掘商业案例》学习笔记,本文侧重数据处理实践,包括:@H_404_3@HASH@H_404_3@对象、自定义@H_404_3@format、以及功能强大的正则表达式@H_404_3@

一:@H_404_3@HASH@H_404_3@对象@H_404_3@@H_404_3@

Hash@H_404_3@对象又称散列表,是根据关键码值而直接进行访问的数据结构,是根据关键码值而直接进行访问的数据结构,@H_404_3@@H_404_3@

sas@H_404_3@提供了两个类来处理哈希表,用于存储数据的@H_404_3@hash@H_404_3@和用于遍历的@H_404_3@hiter,hash@H_404_3@类提供了查找、添加修改删除方法,@H_404_3@hiter@H_404_3@提供了用于定位和遍历的@H_404_3@first@H_404_3@、@H_404_3@next@H_404_3@方法。@H_404_3@@H_404_3@

优点:键值的查找是在内存中进行的,有利于提高性能;@H_404_3@

hash@H_404_3@表可以在数据步运行时,动态的添加更新或删除观测;@H_404_3@@H_404_3@

hash@H_404_3@表中可以很快的定位数据,减少查找次数;@H_404_3@@H_404_3@

常用方法:@H_404_3@

definekey@H_404_3@:定义键@H_404_3@@H_404_3@

Definedata:@H_404_3@定义值@H_404_3@@H_404_3@

definedone@H_404_3@:定义完成,可以载入数据@H_404_3@@H_404_3@

add@H_404_3@添加键值,如在@H_404_3@hash@H_404_3@表中已存在,则忽略;@H_404_3@@H_404_3@

replace@H_404_3@:如果健在@H_404_3@hash@H_404_3@表中存在,则替换,如果不存在则添加键值@H_404_3@@H_404_3@

remove@H_404_3@:清除键值对@H_404_3@@H_404_3@

find@H_404_3@:查找健值,如果存在则将值写入对应变量@H_404_3@@H_404_3@

check@H_404_3@:查找键值,如果存在则返回@H_404_3@rc=@H_404_3@0@H_404_3@,不修改当前变量的值;@H_404_3@@H_404_3@

output@H_404_3@:将@H_404_3@hash@H_404_3@输出到数据集@H_404_3@@H_404_3@

clear@H_404_3@:清空@H_404_3@hash@H_404_3@表,但并不删除对象@H_404_3@@H_404_3@

equal@H_404_3@:判断两个@H_404_3@hash@H_404_3@类是否相等@H_404_3@@H_404_3@

@H_404_3@

find@H_404_3@方法的示例:@H_404_3@@H_404_3@

libname chapt12 'f:\data_model\book_data\chapt12';@H_404_3@

data results;@H_404_3@

if _n_=0 then set chapt12.participants;@H_404_3@@H_404_3@@H_404_3@

if _n_ = 1 then do;@H_404_3@

declare hash h(dataset:'chapt12.participants');@H_404_3@@H_404_3@@H_404_3@

h.definekey('name');@H_404_3@

h.definedata('gender','treatment');@H_404_3@

h.definedone();@H_404_3@

end;@H_404_3@

set chapt12.weight;@H_404_3@

if h.find() = 0 then@H_404_3@

output;@H_404_3@

run;@H_404_3@

@H_404_3@

hiter@H_404_3@对象的引例:@H_404_3@@H_404_3@

data patients;@H_404_3@

length patient_id $ 16 discharge 8;@H_404_3@

input patient_id discharge:date9.;@H_404_3@

datalines;@H_404_3@

smith-4123 15mar2004@H_404_3@

hagen-2834 23apr2004@H_404_3@

smith-2437 15jan2004@H_404_3@

flinn-2940 12feb2004@H_404_3@

;@H_404_3@

data _null_;@H_404_3@

if _n_=0 then set patients;@H_404_3@

declare hash ht(dataset:"patients",ordered:"ascending");@H_404_3@

ht.definekey("patient_id");@H_404_3@

ht.definedata("patient_id","discharge");@H_404_3@

ht.definedone();@H_404_3@

declare hiter iter("ht");@H_404_3@

rc = iter.first();@H_404_3@

do while (rc=0);@H_404_3@

put patient_id discharge:date9.;@H_404_3@

rc = iter.next();@H_404_3@

run;@H_404_3@

用@H_404_3@declare hiter iter("ht");@H_404_3@给@H_404_3@hash@H_404_3@表@H_404_3@ht@H_404_3@定义了一个遍历器@H_404_3@iter@H_404_3@,之后调用@H_404_3@first@H_404_3@方法将遍历器定位到@H_404_3@hash@H_404_3@表的第一条观测,然后使用@H_404_3@next@H_404_3@方法遍历@H_404_3@hash@H_404_3@表中的所有记录并输出。@H_404_3@@H_404_3@

商业实战@H_404_3@-@H_404_3@两个数据集的合并:@H_404_3@@H_404_3@

data both1(drop=rc);@H_404_3@

declare hash plan ();@H_404_3@

rc = plan.definekey ('plan_id');@H_404_3@

rc = plan.definedata ('plan_desc');@H_404_3@

rc = plan.definedone ();@H_404_3@

do until (eof1) ;@H_404_3@

set chapt12.plans end = eof1;@H_404_3@

rc = plan.add ();@H_404_3@

do until (eof2) ;@H_404_3@

set chapt12.members end = eof2;@H_404_3@

call missing(plan_desc);@H_404_3@

rc = plan.find ();@H_404_3@

output;@H_404_3@

stop;@H_404_3@

上述程序可以简化为:@H_404_3@

data both2;@H_404_3@

length plan_id $3 plan_desc $20;@H_404_3@

if _n_ = 1 then do;@H_404_3@

declare hash h(dataset:'chapt12.plans');@H_404_3@

h.definekey('plan_id');@H_404_3@

h.definedata('plan_desc');@H_404_3@

h.definedone();@H_404_3@

call missing(plan_desc);@H_404_3@

end;@H_404_3@

set chapt12.members;@H_404_3@

rc=h.find();@H_404_3@

二:@H_404_3@format@H_404_3@@H_404_3@

自定义@H_404_3@format@H_404_3@:@H_404_3@@H_404_3@

Proc Format;@H_404_3@

Value $ Sex_Fmt@H_404_3@

'F'='@H_404_3@女@H_404_3@'@H_404_3@@H_404_3@

'M'='@H_404_3@男@H_404_3@'@H_404_3@@H_404_3@

Other = '@H_404_3@未知@H_404_3@';@H_404_3@@H_404_3@

Value Age_Dur@H_404_3@

Low-10="10@H_404_3@岁以下@H_404_3@"@H_404_3@@H_404_3@@H_404_3@

11-13="11-13@H_404_3@岁@H_404_3@"@H_404_3@@H_404_3@

14-<15="14-15"@H_404_3@

15-High="15@H_404_3@岁以上@H_404_3@";@H_404_3@@H_404_3@

Run;@H_404_3@

应用:@H_404_3@

Datatest;@H_404_3@

Setsashelp.class(keep=sex age);@H_404_3@

x=put(sex,$sex_fmt);y=put(age,age_dur.);@H_404_3@

三:正则表达式:@H_404_3@

/.../@H_404_3@一个正则表达式的起止;@H_404_3@@H_404_3@

|@H_404_3@@H_404_3@数项之间的选择,“或”运算;@H_404_3@@H_404_3@

()@H_404_3@匹配组,标记一个子表达式的开始和结束位置;@H_404_3@@H_404_3@

.@H_404_3@除换行符以外的任意字符;@H_404_3@@H_404_3@

\w@H_404_3@任一单词字符,数字大小写字母以及下划线@H_404_3@@H_404_3@

\W@H_404_3@任一非单词字符@H_404_3@@H_404_3@

\s@H_404_3@任一空白字符,包括空格、制表符、换行符、回车符、中文全角空格等;@H_404_3@@H_404_3@

\S@H_404_3@任一非空白字符,@H_404_3@@H_404_3@

\d0-@H_404_3@9@H_404_3@任一数字@H_404_3@@H_404_3@

\D@H_404_3@任一非数字字符@H_404_3@@H_404_3@

[...]@H_404_3@

[^...]@H_404_3@

[a-z]@H_404_3@从@H_404_3@a@H_404_3@到@H_404_3@z@H_404_3@@H_404_3@

[^a-z]@H_404_3@不在从@H_404_3@a@H_404_3@到@H_404_3@z@H_404_3@范围内的任意字符@H_404_3@@H_404_3@

^@H_404_3@匹配输入字符串的开始位置@H_404_3@@H_404_3@

$@H_404_3@匹配输入字符串的结尾位置@H_404_3@@H_404_3@

\b@H_404_3@描述单词的前或后边界@H_404_3@@H_404_3@

\B@H_404_3@表示非单词边界@H_404_3@@H_404_3@

*@H_404_3@匹配@H_404_3@0@H_404_3@次或多次@H_404_3@@H_404_3@

+@H_404_3@匹配一次或多次@H_404_3@@H_404_3@

?@H_404_3@匹配零次或@H_404_3@一次@H_404_3@@H_404_3@

{n}@H_404_3@匹配@H_404_3@n@H_404_3@次@H_404_3@@H_404_3@

{n,}@H_404_3@匹配@H_404_3@n@H_404_3@次以上@H_404_3@@H_404_3@

404_3@匹配@H_404_3@n@H_404_3@到@H_404_3@m@H_404_3@次@H_404_3@@H_404_3@

@H_404_3@

常用函数:@H_404_3@

Prxparse@H_404_3@定义一个正则表达式@H_404_3@@H_404_3@

Prxmatch@H_404_3@返回匹配模式的首次匹配位置@H_404_3@@H_404_3@

Call prxsubstr@H_404_3@返回匹配模式在目标字符串的开始位置和长度@H_404_3@@H_404_3@

Prxposn@H_404_3@返回正则表达式子表达式对应的匹配模式值@H_404_3@@H_404_3@

Callprxposn@H_404_3@返回正则表达式子表达式对应的匹配模式和长度@H_404_3@@H_404_3@

Cal lprxnext@H_404_3@返回匹配模式在目标字符串中的多个匹配位置和长度@H_404_3@@H_404_3@

Prxchange@H_404_3@替代匹配模式的值@H_404_3@@H_404_3@

Call prxchange@H_404_3@替代匹配模式的值@H_404_3@@H_404_3@

eg1@H_404_3@:@H_404_3@@H_404_3@

if _n_ = 1 then pattern_num = rxparse("/cat/");@H_404_3@

@H_404_3@

retain pattern_num;@H_404_3@

input string $30.;@H_404_3@

position = rxmatch(pattern_num,string);@H_404_3@

file print;@H_404_3@

put pattern_num= string= position=;@H_404_3@

there is a cat in this line.@H_404_3@

does not match cat@H_404_3@

cat in the beginning@H_404_3@

at the end,a cat@H_404_3@

cat@H_404_3@

eg2@H_404_3@:数据验证@H_404_3@@H_404_3@

data match_phone;@H_404_3@

set chapt12.phone_numbers;@H_404_3@

if _n_ = 1 then pattern = prxparse("/\(\d\d\d\) ?\d\d\d-\d{4}/");@H_404_3@

retain pattern;@H_404_3@

if prxmatch(pattern,phone) gt 0 then output;@H_404_3@

找出不匹配的手机号码@H_404_3@

data unmatch_phone;@H_404_3@

where not prxmatch("/\(\d\d\d\) ?\d\d\d-\d{4}/",phone);@H_404_3@

Eg3:@H_404_3@提取匹配某种模式的字符串@H_404_3@@H_404_3@

data extract;@H_404_3@

pattern = prxparse("/\(\d\d\d\) ?\d\d\d-\d{4}/");@H_404_3@

if missing(pattern) then do;@H_404_3@

put "error in compiling regular expression";@H_404_3@

stop;@H_404_3@

end;@H_404_3@

length number $ 15;@H_404_3@

input string $char80.;@H_404_3@

call prxsubstr(pattern,string,start,length);@H_404_3@

if start gt 0 then do;@H_404_3@

number = substr (string,length);@H_404_3@

number = compress(number," ");@H_404_3@

output;@H_404_3@

keep number;@H_404_3@

this line does not have any phone numbers on it@H_404_3@

this line does: (123)345-4567 la di la di la@H_404_3@

also valid (123) 999-9999@H_404_3@

two numbers here (333)444-5555 and (800)123-4567@H_404_3@

eg4@H_404_3@提取名字@H_404_3@@H_404_3@

data ReversedNames;@H_404_3@

input name & $32.;@H_404_3@

datalines;@H_404_3@

Jones,Fred@H_404_3@

Kavich,Kate@H_404_3@

Turley,Ron@H_404_3@

Dulix,Yolanda@H_404_3@

data FirstLastNames;@H_404_3@

length first last $ 16;@H_404_3@

keep first last;@H_404_3@

retain re;@H_404_3@

if _N_ = 1 then@H_404_3@

re = prxparse('/(\w+),(\w+)/');@H_404_3@

set ReversedNames;@H_404_3@

if prxmatch(re,name) then@H_404_3@

do;@H_404_3@

last = prxposn(re,1,name);@H_404_3@

first = prxposn(re,2,255)">注:@H_404_3@1,2@H_404_3@分别代表正则表达式中的两个组@H_404_3@@H_404_3@

eg5@H_404_3@提取符合规定的名字@H_404_3@@H_404_3@

data old;@H_404_3@

input name $60.;@H_404_3@

Judith S Reaveley@H_404_3@

Ralph F. Morgan@H_404_3@

Jess Ennis@H_404_3@

Carol Echols@H_404_3@

Kelly Hansen Huff@H_404_3@

Judith@H_404_3@

Nick@H_404_3@

Jones@H_404_3@

data new;@H_404_3@

length first middle last $ 40;@H_404_3@

re1 = prxparse('/(\S+)\s+([^\s]+\s+)?(\S+)/o');@H_404_3@

re2 = prxparse('/(\S+)(\s+)([^\s]+\s+)(?)(\S+)/o');@H_404_3@

set old;@H_404_3@

id1=prxmatch(re1,255)">id2=prxmatch(re2,255)">if id1 then@H_404_3@

first = prxposn(re1,255)">middle = prxposn(re1,255)">last = prxposn(re1,3,255)">if id2 then test=prxposn(re1,4,255)">put test=;@H_404_3@

Eg6:@H_404_3@返回匹配模式的多个位置@H_404_3@@H_404_3@

expressionid = prxparse('/[crb]at/');@H_404_3@

text = 'the woods have a bat,cat,and a rat!';@H_404_3@

start = 1;@H_404_3@

stop = length(text);@H_404_3@

call prxnext(expressionid,stop,text,position,255)">do while (position > 0);@H_404_3@

found = substr(text,255)">put found= position= length=;@H_404_3@

call prxnext(expressionid,255)">注:首次执行@H_404_3@call prxnext@H_404_3@返回一个@H_404_3@position@H_404_3@,然后进入循环,在抽取满足条件的子串中,再次执行@H_404_3@all prxnext@H_404_3@,此时会返回下一个匹配的@H_404_3@position@H_404_3@;@H_404_3@@H_404_3@

Eg7:@H_404_3@替换文本@H_404_3@@H_404_3@

data cat_and_mouse;@H_404_3@

input text $char40.;@H_404_3@

length new_text $ 80;@H_404_3@

if _n_ = 1 then match = prxparse("s/[Cc]at/mouse/");@H_404_3@

retain match;@H_404_3@

call prxchange(match,-1,new_text,len,trunc,num);@H_404_3@@H_404_3@@H_404_3@

if trunc then put "note: new_text was truncated";@H_404_3@

the Cat in the hat@H_404_3@

there are two cat cats in this line@H_404_3@

here is no replacement@H_404_3@

run;@H_404_3@

猜你在找的正则表达式相关文章