使用SAS程序导入并清洗混乱数据集的实现方法咨询
SAS清洗混乱CSV数据集的实现方案
这个待导入的CSV数据集存在以下几类脏数据问题:
- 字段值内部包含逗号,会干扰默认的逗号分隔逻辑
- 字符串字段内存在转义双引号(
""代表原内容的单个双引号) - 首尾两个字段
Datelisted、Contacts为JSON数组格式,需要提取有效字段 - 存在缺值、个别行因字段未加引号导致的错位问题
第一步:按带引号字段的规则导入原始数据
使用SAS的dsd参数自动处理带引号的字段,避免字段内的逗号被识别为分隔符:
/* 替换为你的实际文件存储路径 */ filename raw_csv "C:\files\dirty_data.csv"; data raw_import; infile raw_csv dsd delimiter=',' firstobs=2 missover lrecl=32767; informat Datelisted $200. Shop $100. Region $200. Product $200. Color $200. Price 8. Discount $10. Contacts $1000.; format Datelisted $200. Shop $100. Region $200. Product $200. Color $200. Price 8.2 Discount $10. Contacts $1000.; input Datelisted Shop Region Product Color Price Discount Contacts; run;
导入后大部分正常行的字段拆分结果正确,仅个别未加引号的错位行需要后续单独修正。
第二步:解析Datelisted字段的JSON内容
通过正则表达式提取JSON内的上架日期、上架人两个有效字段:
data parse_date; set raw_import; /* 提取上架日期并转成SAS日期格式 */ re_date = prxparse('/"date":"(.*?)"/i'); if prxmatch(re_date, Datelisted) then list_date = input(prxposn(re_date,1,Datelisted), mmddyy10.); format list_date yymmdd10.; /* 提取上架人 */ re_lister = prxparse('/"listed by":"(.*?)"/i'); if prxmatch(re_lister, Datelisted) then listed_by = prxposn(re_lister,1,Datelisted); drop re_date re_lister Datelisted; run;
第三步:解析Contacts字段的联系人信息
将JSON数组内的多个联系人拆分为单独行存储,方便后续使用:
data parse_contacts; set parse_date; length contact_name $50 contact_phone $20; /* 统计当前行的联系人数量 */ contact_num = count(Contacts, '"name":'); if contact_num > 0 then do i=1 to contact_num; /* 循环提取每个联系人的姓名和电话 */ re_name = prxparse(cats('/"name":"(.*?)"(.*?){',i,'}/i')); if prxmatch(re_name, Contacts) then contact_name = prxposn(re_name,1,Contacts); re_phone = prxparse(cats('/"contact":"(.*?)"(.*?){',i,'}/i')); if prxmatch(re_phone, Contacts) then contact_phone = prxposn(re_phone,1,Contacts); output; end; /* 处理联系人字段为空的行 */ else output; drop Contacts contact_num i re_name re_phone; run;
第四步:修正错位异常行
本数据集中仅第三行存在错位问题,可通过特征匹配后修正字段值:
data final_clean; set parse_contacts; /* 匹配错位行的唯一特征:上架日期为2021-01-01、上架人为user、price为空 */ if list_date='01JAN2021'd and listed_by='user' and Price=. then do; Product = "Kirnawa, PS, pattern, 5"""; Color = ""; Price = 23.12; Discount = ""; end; /* 可选操作:如果需要将Region、Color的多值拆分为单独行,可取消下方代码注释 length single_region $50 single_color $20; do i=1 to countw(Region, ','); single_region = strip(scan(Region, i, ',')); do j=1 to countw(Color, ','); single_color = strip(scan(Color, j, ',')); output; end; end; drop Region Color i j; */ run;
最终输出的
final_clean数据集就是清洗完成的结构化数据,可直接用于后续统计分析。
内容的提问来源于stack exchange,提问作者konsteinuser
相关产品推荐
相关产品推荐

