SAS学习1:INPUT语句

主要学习资料:《SAS应用统计分析》
大二的时候专门开过这门课,比较困惑的是统计常用的R却没有单独开课,所以SAS应该是大学期间学的最好的统计软件,不过好久没有学过,由于实习需要,现在只能从头来过。
由于这本书第一章先讲描述分析,直接跳过了基本语法内容,所以先从第12章开始,看INPUT语句的用法。

列表输入法(list input)

特点:INPUT后跟的变量顺序与DATALINES中的数据顺序对应,数据用空格隔开

DATA test;
  INPUT x1 x2 $;
DATALINES;
1 M
2 F
;

当分隔符不为空格,比如为逗号时,在INFILE语句中用DLM选项指定分隔符

DATA test;
  INFILE DATALINES DLM = ",";
  INPUT x1 x2 $;
DATALINES;
1,M
2,F
;

当分隔符为逗号,且需要忽略引号,直接读取引号中内容时,用DSD选项:

DATA test;
  INFILE DATALINES DSD;
  INPUT x1 x2 $;
DATALINES;
1,"M"
2,,
在list input中指定输入格式

这种要求通常发生在数据为时间序列数据时。

  1. 方法一:在DATA步中加INFORMAT语句指定变量的格式
DATA test;
  INFORMAT dob MMDDYY10.;
  INPUT name $ dob;
DATALINES;
john 10/21/1965
;

也可以用于指定字符型变量的长度,因为在SAS中字符变量一般默认8个字符长度:

DATA test;
  INFORMAT name $ 20., dob MMDDYY10.;
  INPUT name$ dob;
DATALINES;
ihavealongname 10/21/1965
;
  1. 方法二:在INPUT语句中,在变量后跟冒号直接指定变量对应的格式
DATA test;
  INFILE DATALINES DLM = ',';
  INPUT name $ dob : MMDDYY10.;
DATALINES;
john,10/21/1965
;
格式修正符

列表输入法中,若变量后跟格式修正符&,则不再以空格作为分隔符,此法可以将两个用空格分隔的变量读成一个变量。

DATA test;
  INPUT id name & : $30. score;
DATALINES;
1 jame smith 20;

栏位输入法(column input)

栏位输入法要求数据按栏位对齐,按照固定格式读取数据

DATA test;
  INPUT id 1-3
    gender $ 4;
DATALINES;
001M
2  F

这个方法现在一般很少看到使用,因为用于读取日期和非标准值数据很麻烦,但也有它的优点:不需要考虑数据是左对齐还是右对齐,只要是在栏位内的值都能读取。

格式化输入(formatted input)

格式化输入需要用栏位指针@指定起始位置,并在变量后声明变量的格式。
一般数值数据的读取格式为W.d,其中W表示数值变量的长度,d表示小数位数,例如123按照3.2读取,结果为1.23;而1.23按照4.读取,结果却仍然是1.23,这是为什么呢?

  • 第一,小数点占一个栏位
  • 第二,数值本身的小数点优先于W.d中隐含的小数点
DATA test;
  INPUT @1 id 3.
    @4 date MMDDYY10.;
DATALINES;

注意通过制定栏位和指针,可以反复读取数据。

每个被试读取多行数据

此时需要使用行指针#,来指明读取数据位于哪一行。注意只有当一行数据读取完后行指针才会移动到下一行,否则会报错

DATA test;
  INPUT #1 ID 1-3 @4 dob MMDDYY10.
    #2  weight 1-3 @4 height 3.;
DATALINES;
00110/21/1997
100180
;

但是假如一个被试有多行数据,只需读取前两行,则需要在INPUT语句末尾加上#N,表示该被试实际上有N行数据

DATA test
  INPUT #1id dob
    #2 address #6;

输入格式列表

这个输入方法就比较有意思了。首先SAS中名字相似的变量可以一起输入,其次格式相同的变量可以用括号括起来一起输入。
举个🌰:

DATA test;
  INPUT @1 id $3.
    @4 (ques1-ques4 ques4_1 ques5-quest9) (1.)
    @20 (dob leave_date)(MMDDYY10.);

还有一个更厉害的操作:假如相似的变量不是连着放在一起的,而是中间有其他变量隔开,此时可以在栏位中加上+/-号,表示向前或向后移动指针。
例如假如对一组病人做了12次测试,每次测两个指标,每个指标占3个栏位,测试结果按照:

ID SBP1 DPB1 SBP2 DBP2 ... SBP12 DBP12

排列,我们可以这么读这批变量

DATA test
  INPUT @1 id $3.
    @4 (SBP1-SBP12)(3. +3)
    @7 (DBP1-DBP12)(3. +3);

@和@@

这两个符号的使用就更巧妙了,因为需要搞清楚SAS读数据的原理:

  1. 首先DATA步创建临时数据集,然后INPUT语句创建变量,此时每个变量下都是空值,然后运行到DATALINES语句表示要从下面的内容中读入数据
  2. 此时每读一行为一个DATA步循环,读取后将变量存储到一个临时的空间中(忘了叫什么名字了),直到读到数据集末尾的分号;,才将所有的数据引入数据集中。
    也就是说,SAS完成一个INPUT循环后,就会自动将指针移到下一行,下一次开始INPUT循环后会从下一行开始读取。假如DATA步里有多个INPUT语句,则第二个INPUT语句只能读到第二行的内容。这时就需要@@@了。

@表示保持此行,即INPUT语句完成该次循环后,指针不会跳转到下一行,如果遇到下一个没有以@结尾的INPUT语句,则会跳转到下一行,或者如果遇到DATALINES,则会跳转到下一行。
@@表示强制执行此行,即INPUT语句完成该次循环后,即使遇到了DATALINES也不会跳转到下一行。
举个🌰:

DATA test;
  INPUT X Y @@;
DATALINES;
1 2 7 9 3 4 10 12
15 18
;

读取的结果是:

(1,2) (7,9),...,(15,18)

但如果是:

DATA test
  INPUT X Y @;
DATALINES;
1 2 7 9 3 4 10 12
15 18
;

则结果仍然是

(1,2) (15,18)

不规则数据的读取

到这里要加大力度了,首先对于不平衡数据:

组别 观测值
C 1 2 3 4 5
T 2 3 4

这种数据应该如何读取?
当然可以一步一步输入:

DATA t;
  INPUT group $ x @@;
DATALINES;
c 1 c 2 c 3 c 4 c 5
t 2 t 3 t 4

但是数据多了就很麻烦
给出一个究极解决方法:

DATA test;
  RETAIN GROUP;
  INPUT DUMMY $ @@;
  IF DUMMY = 'C' OR DUMMY = 'T' THEN GROUP = DUMMY;
  ELSE DO;
    X = INPUT(DUMMY, 5.0)
    OUTPUT;
  END;
  DROP DUMMY;
DATALINES;
C 1 2 3 4 5
T 2 3 4;

解析要点:

  • INPUT语句,用@@强制保持此行,逐个读入数值
  • RETAIN语句:使得每次DATA步循环开始时,变量GROUP会保持上一次读取的值,不会被自动设置为缺失。
  • INPUT()函数,当DUMMY的值为数字内容的字符时,将DUMMY的值赋给X,同时用INPUT转化成数值格式
  • OUTPUT语句,用该OUTPUT代替DATA步末尾的OUTPUT,使得读完X的值后才输出该次观测,而不会读完做完IF语句就直接输出,此时只会有组名而没有对应数据

当然,还有更复杂的多变量不平衡数据的读入:



读这个数据就需要使用多重循环了:

DATA test;
  DO GENDER = 'M','F';
    DO GROUP  = 'A','B','C';
      INPUT DUMMY $ @;
      DO WHILE (DUMMY NE '#');
        SCORE = INPUT(DUMMY, 6.0);
        OUTPUT;
        INPUT DUMMY $ @;
      END;
    END;
END;
DROP DUMMY;

DATALINES中用#分割不同组的数据
或者还有另一种方法

DATA test;
  RETAIN GROUP GENDER;
  LENGTH GROUP GENDER $ 1;
  INPUT DUMMY $ @@;
  IF VERIFY(DUMMY, 'ABCMF ') = 0 THEN DO;
    GROUP = SUBSTR(DUMMY,1,1);
    GENDER = SUBSTR(DUMMY,2,1);
    DELETE;
  END;
  ELSE SCORE = INPUT(DUMMY,6.);
  DROP DUMMY;
DATALINES;
AM 20 30 40 20 50
BM 70 80 90
...
;

要点解读:

  • RETAIN语句的功能和前面一样
  • LENGTH语句指定变量长度为1个字符
  • 首先读入DUMMY,此时默认为8个字符,因此读入两个字母后会在尾部自动添加6个空格,因此利用VERIFY()函数比对时要在参数中加空格。如果确实在字符串中,则GROUP值为字符串的第一个数值,GENDER值为字符串第二个数值。然后删除此行观测(因为X没有读到值)
  • 进入下一个DATA步的循环,此时DUMMY内容为数值,赋给SCORE,运行到末尾,自动输出该次观测。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容