楼主: MyLoveSas
9875 10

[求助]批量将文本文件中数据导入SAS数据集 [推广有奖]

  • 0关注
  • 1粉丝

本科生

91%

还不是VIP/贵宾

-

威望
0
论坛币
18 个
通用积分
0
学术水平
0 点
热心指数
5 点
信用等级
0 点
经验
837 点
帖子
31
精华
0
在线时间
201 小时
注册时间
2009-2-20
最后登录
2012-7-20

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
<p>碰到如下问题,求教各位大侠:</p><p>文本格式的文件,需要导入到SAS数据集中。原始软件存储如下:不同部分用空行隔开,同一部分需要生成一个数据集,一次生成所有的数据集,另外文本文件中每一部分第一行描述的是变量名称,最后一个要求是数值型变量,前面都是字符型变量,每个数据包含的变量个数事先也是不知道的。</p><p>不知道我说清楚了没。文件格式实例见附件。</p><p>&nbsp;</p>
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:sas数据集 文本文件 数据导入 数据集 字符型变量 SAS 数据集 文本文件 批量

沙发
xmok77 发表于 2009-3-4 19:01:00 |只看作者 |坛友微信交流群
附件在哪?
以出世的精神做入世的事情

使用道具

藤椅
MyLoveSas 发表于 2009-3-4 20:45:00 |只看作者 |坛友微信交流群

回复:(xmok77)附件在哪?[em09]

<p>实例文件!</p> 300164.txt (553 Bytes) <br/>

使用道具

板凳
xing-_-he 发表于 2009-3-6 22:22:00 |只看作者 |坛友微信交流群

回复:[求助]批量将文本文件中数据导入SAS数据集

<p>代码如下:</p><p>===============================================================================================================</p><p>%let g_outfile = "E:\OutFile.csv" ;<br/>%macro CreateTable;</p><p>data record( keep = fieldtype startline endline ) field( keep = field1-field6 fieldtype ) ;<br/>&nbsp; <br/>&nbsp; %local EndBlock;<br/>&nbsp; %let EndBlock = _%substr(%sysfunc(ranuni(0),9.7),3);</p><p>&nbsp; retain startfield startcolumn startline ;<br/>&nbsp; retain readstart 0 ;<br/>&nbsp; retain readfirst 0 ;<br/>&nbsp; retain readfield 0 ;<br/>&nbsp; retain readstat&nbsp; 0 ;<br/>&nbsp; retain startline 0 ;<br/>&nbsp; retain endline&nbsp;&nbsp; 2 ;<br/>&nbsp; retain curline&nbsp;&nbsp; 0 ;<br/>&nbsp; retain fileline&nbsp; 1 ;<br/>&nbsp; infile &amp;g_outfile&nbsp; _infile_= memfile END = endoffile missover dlm = ',' ;<br/>&nbsp; input (field1-field6) ($) ;<br/>&nbsp; fileline+1 ;<br/>&nbsp; curline+1 ;</p><p>&nbsp; if endoffile = 1 then<br/>&nbsp;&nbsp;&nbsp; do ;<br/>&nbsp;&nbsp; endline = curline ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output record ;<br/>&nbsp;&nbsp; goto &amp;EndBlock ;<br/>&nbsp;&nbsp;&nbsp; end ;</p><p>&nbsp; if readstart = 0 then <br/>&nbsp;&nbsp;&nbsp; do ;<br/>&nbsp;&nbsp; readstart = 1 ;<br/>&nbsp;&nbsp; readstat = 1 ;<br/>&nbsp;&nbsp; readfirst = 1 ;<br/>&nbsp;&nbsp; readfield = 0 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldtype+1 ;<br/>&nbsp;&nbsp; startline = fileline ;<br/>&nbsp;&nbsp; output field ;<br/>&nbsp;&nbsp; goto &amp;EndBlock ;<br/>&nbsp;end ;</p><p>&nbsp; len = length( memfile )-1 ;<br/>&nbsp; if len = 0 then <br/>&nbsp;&nbsp;&nbsp; do ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readfield = 1 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readstat = 0 ;<br/>&nbsp;&nbsp; endline = curline-1 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output record ;<br/>&nbsp;&nbsp; if readfirst eq 1 then readfirst = 0 ;<br/>&nbsp;&nbsp; startline = fileline ;<br/>&nbsp;&nbsp; startline+1 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto &amp;EndBlock ;<br/>&nbsp;&nbsp;&nbsp; end ;</p><p>&nbsp; if readfield = 1 then <br/>&nbsp;&nbsp;&nbsp; do ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readfield = 0 ;<br/>&nbsp;&nbsp; readstat = 1 ;<br/>&nbsp;&nbsp; fieldtype+1 ;<br/>&nbsp;&nbsp; output field ;<br/>&nbsp;&nbsp; goto &amp;EndBlock ;<br/>&nbsp;&nbsp;&nbsp; end ;</p><p>&nbsp; if readstat = 1 then goto &amp;EndBlock ;</p><p>&nbsp; &amp;EndBlock.:</p><p>run ;</p><p>proc sort data = record ;<br/>&nbsp; by fieldtype ;<br/>run ;<br/>proc sort data = field ;<br/>&nbsp; by fieldtype ;<br/>run ;</p><p>data mergetable ;<br/>&nbsp; merge field record ;<br/>&nbsp; by fieldtype ;<br/>run ;</p><p>data _null_ ;<br/>&nbsp; set mergetable ;<br/>&nbsp; call symput( "recordcount" , _n_ ) ;<br/>run ;</p><p>%macro appendfield ;<br/>%do i = 1 %to &amp;recordcount ;<br/>&nbsp; %global v&amp;i ;<br/>&nbsp; data _null_ ;<br/>&nbsp;&nbsp;&nbsp;&nbsp; set mergetable ;<br/>&nbsp; if _n_ = &amp;i ;<br/>&nbsp; %do j = 1 %to 6 ;<br/>&nbsp;&nbsp;&nbsp; call symput( "v&amp;j" , field&amp;j ) ;<br/>&nbsp; %end ;<br/>&nbsp; put startline = ;<br/>&nbsp; put recordcnt = ;<br/>&nbsp; call symput( "linestart" , startline ) ;<br/>&nbsp; call symput( "lineend"&nbsp;&nbsp; , endline&nbsp;&nbsp; ) ;<br/>&nbsp;&nbsp; run ;</p><p>&nbsp; data Table&amp;i ;<br/>&nbsp;&nbsp;&nbsp; infile &amp;g_outfile firstobs = &amp;linestart obs = &amp;lineend missover dsd ;<br/>&nbsp;input (&amp;v1 &amp;v2 &amp;v3 &amp;v4 &amp;v5 &amp;v6) ($) ;<br/>&nbsp; run ;</p><p>&nbsp; data Table&amp;i.(drop = count);<br/>&nbsp;&nbsp;&nbsp; set Table&amp;i ;<br/>&nbsp;COUNTCNT = int( count ) ;<br/>&nbsp; run ;</p><p>%end ;<br/>%mend appendfield ;</p><p>%appendfield </p><p>%mend CreateTable ;</p><p>%CreateTable ;</p><p>===============================================================================================================</p><p>遗留问题:</p><p>1、整型变量名要求全部相同(上代码中是COUNT),对变量名不同的问题目前还没有想到好的办法。还请各位大侠看是否有好的点子一同分享;</p><p>2、变量个数最大值要求在一定范围内(这个问题应该不大);</p><br>xmok77
&nbsp;金钱&nbsp;+100
&nbsp;奖励&nbsp;2009-3-7 11:07:41

使用道具

报纸
yongyitian 发表于 2009-3-7 09:35:00 |只看作者 |坛友微信交流群
<p>Try&nbsp;the following code to se if you can&nbsp;find the number of blocks (the number of datasets to be created) and <br/>the number of variables in each block (dataset). These numbers are saved in macro variables: <br/>Num_of_Datasets, NVar_in_Dataset1, NVar_in_Dataset2, ..., and can be used in other macros for input the data.</p><p><br/>data _NULL_;<br/>&nbsp; infile 'D:\MySAS\RawData.txt'; <br/>&nbsp; if _N_ = 1 then Num_block = 1;<br/>&nbsp; retain Num_block Num_var;<br/>&nbsp; input line $80.;<br/>&nbsp; if line = null then Num_block +1;<br/>&nbsp; dataset_name='Dataset'!!trim(left(Num_block));<br/>&nbsp;&nbsp;&nbsp;&nbsp; if line ^= null then Num_var = count(line, ',')+1;<br/>&nbsp; call symput('NVar_in_Dataset'!!trim(left(Num_block)), Num_var);<br/>&nbsp;&nbsp;&nbsp;&nbsp; call symput('Num_of_Datasets', Num_block);<br/>run;<br/>%put _user_; /* to check the number saved in the macro variables */</p><p></p><br>xmok77
&nbsp;金钱&nbsp;+100
&nbsp;奖励&nbsp;2009-3-7 11:08:30

使用道具

地板
xmok77 发表于 2009-3-7 11:09:00 |只看作者 |坛友微信交流群
受益匪浅
以出世的精神做入世的事情

使用道具

7
wangwangwang110 发表于 2009-3-7 17:58:00 |只看作者 |坛友微信交流群
<p>给你参考一下我最近导入数据源文件为002001.csv-002274.csv的代码,希望对你有帮助!</p><p>/*导入文本文件*/<br/>%macro readraw(first=2001,last=2274);<br/>&nbsp;&nbsp; %local num;<br/>&nbsp;&nbsp; %do num=&amp;first %to &amp;last;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proc import out=exer.sz00&amp;num<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datafile="c:\0\exercise\00&amp;num.csv"<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms=csv replace;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getnames=yes;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run;<br/>&nbsp;&nbsp; %end;<br/>%mend readraw;<br/>%readraw(first=2001,last=2274);<br/>run;&nbsp;&nbsp; </p><p>/*重命名变量名*/<br/>%macro rena(first=2001,last=2274);<br/>&nbsp;&nbsp; %local num;<br/>&nbsp;&nbsp; %do num=&amp;first %to &amp;last;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data exer.alsz00&amp;num;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set exer.sz00&amp;num(rename=(Var1=symbol Var2=name Var3=tdate Var4=lprice));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run;<br/>&nbsp;&nbsp; %end;<br/>%mend rena;<br/>%rena(first=2001,last=2274);&nbsp; </p><p>/*串联各数据集*/<br/>%macro comb(first=2001,last=2274);<br/>&nbsp;&nbsp; %local num;<br/>&nbsp;&nbsp; %do num=&amp;first %to &amp;last;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data exer.combine&amp;num;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set&nbsp; exer.alsz00&amp;num exer.combine%eval(&amp;num-1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run;<br/>&nbsp;&nbsp; %end;<br/>%mend comb;<br/>%comb(first=2001,last=2274);&nbsp; <br/>&nbsp;</p>

使用道具

8
MyLoveSas 发表于 2009-3-7 22:21:00 |只看作者 |坛友微信交流群
<p>5楼的code基本能解决我的问题,谢谢各位的帮助。测试过程中发现使用infile语句操作的一个问题,通过几个简单程序说明如下:</p><p><font color="#f73809">示例代码1:</font></p><p>data temp1 ;</p><p>infile cards dlm = ',' ;</p><p><font color="#2b4dd5">/***************************************************************************************************************************************************************</font></p><p><font color="#2b4dd5">first和second的采用默认的8位字符长度,因此取值超过8位的被截取,不能得到想要的结果.</font></p><p><font color="#2b4dd5">注:分隔符在生成变量观测是起到了一定的作用。</font></p><p><font color="#2b4dd5">**************************************************************************************************************************************************************/</font></p><p>input first $ second $ ;</p><p>cards ;</p><p>12345678,1234567890</p><p>123456789,1234567890</p><p>;</p><p>run ;</p><p><br/><font color="#f70909">示例代码2:</font></p><p>data temp2;</p><p>infile cards dlm = ',' ;</p><p><font color="#1111ee">/********************************************************************************************************************************************</font></p><p><font color="#1111ee">first和second变量设置为其所有可能取值中的最长取值的长度,生成的观测存在问题,感觉分隔符“,”被忽略了;</font></p><p><font color="#1111ee">*******************************************************************************************************************************************/</font></p><p>input first $9. &nbsp;second $10. &nbsp;;</p><p>cards ;</p><p>12345678,1234567890</p><p>123456789,1234567890</p><p>;</p><p>run ;</p><p><font color="#ff0000">示例代码3:</font></p><p>data temp3;</p><p>infile cards dlm = ',' ;</p><p><font color="#1111ee">/************************************************************************************************************************************************************</font></p><p><font color="#1111ee">显示设置first和second变量的长度且均设置为系统默认的长度8,变量所有的可能取值长度都是8,此时生成的观测仍然存在问题</font></p><p><font color="#1111ee">************************************************************************************************************************************************************/</font></p><p>input first $8. &nbsp;second $8. &nbsp;;</p><p>cards ;</p><p>12345678,12345678</p><p>12345678,12345678</p><p>;</p><p>run ;</p><p><font color="#ff0000">示例代码4:</font></p><p>data temp4;</p><p>infile cards ;</p><p><font color="#1111ee">/************************************************************************************************************************************************************</font></p><p><font color="#1111ee">显示设置first和second变量的长度且均设置为系统默认的长度8,变量所有的可能取值长度都是8,且去掉dlm选项设置,此时生</font></p><p><font color="#1111ee">成的观测仍然存在问题</font></p><p><font color="#1111ee">************************************************************************************************************************************************************/</font></p><p>input first $8. &nbsp;second $8. &nbsp;;</p><p>cards ;</p><p>12345678,12345678</p><p>12345678,12345678</p><p>;</p><p>run ;</p><p>从以上示例来看,如果显示设置了变量的长度,则sas系统忽略分隔符,但是以上的四种方式也不能得到预期的结果。那位大侠能介绍下infile语句的使用细则吗?或者是否能够提供相关说明的详细资料?谢谢了先!!!</p>

使用道具

9
sqlai 发表于 2009-3-8 03:36:00 |只看作者 |坛友微信交流群
<br/>你所发现的问题是因为:示例中 input设定的变量类型全部都设定为字符型了 (全部都加了美元符号 $)!!<img alt="" src="Skins/Default/emot/em03.gif" style="margin: 6px; cursor: pointer;"/><br/><br/>如果要导入的是数值型变量,sas可以自动识别位数,不需要设定长度,input first second;<br/>要是设定长度,反而无法读入长度不同数值。<br/><br/>示例2<br/>input first $9.  second $10.  ;<br/>是按照字符读入数据,并且你也给定了长度,逗号分隔符也将被当作字符一起读入到变量中。<br/><br/>示例3,4<br/>input first $8.  second $8.  ;<br/>同样的毛病,逗号分隔符位于第二个变量开始读入的起点位置,被当作字符读入变量second中了.<br/><br/>对于定长的字符串数据<br/>aaa bbb<br/>aaa bbb<br/><br/><br/>使用下面的都可以<br/>input a$ b$; *sas按照默认的分隔符,或者指定的分隔符自动判断长度;<br/>input a$1-3 b$5-7; *给出绝对位置的引用,表示1~3个字符是第一个变量,中间的空格或者分隔符也要占位,因此第二个变量是从第5个字符开始;<br/>input a$3. +1 b$3.;*给出字符变量长度,有sas自动根据分隔符发现第一个字符后取3个作为第一个变量,+1 表示让sas向右移动一个字符之后再开始扫描第二个变量;<br/>input first $1-3 +1 second $3.; *这个是上面两种字符定位方式的混用,先绝对定位,然后强制移动1位,然后自动搜索定长的字符变量;<br/><br/><br/>
change is easy, improvement is difficult

使用道具

10
MyLoveSas 发表于 2009-3-8 09:00:00 |只看作者 |坛友微信交流群
<p>在input语句前面用length语句来设置变量的长度(设定为大于或等于其所有可能取值中的最大长度),可以成功读入非定常的带有分隔符的字符数据。如将示例代码2改为:</p><p>data temp2;</p><p>infile cards dlm = ',' ;</p><p>length first $9.&nbsp; second $10.&nbsp; ;</p><p>input first $&nbsp; second $ ;</p><p>cards ;</p><p>12345678,1234567890</p><p>123456789,1234567890</p><p>;</p><p>run ;</p><p>SAS内部的执行行为还是蛮难捉摸的。</p><br>xmok77
&nbsp;金钱&nbsp;+100
&nbsp;奖励&nbsp;2009-3-8 9:13:55

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-28 22:24