Categories
读书有感

≪统计学习精要(The Elements of Statistical Learning)≫课堂笔记(六)

呃,我觉得我的笔记稍稍有点混乱了...这周讲的依旧是线性分类器,logit为主。anyway,大家将就着看吧。

logistic regression

首先我们考虑最一般的,有K种分类的场合。依旧,我们用来代替作为观测到的分类结果,那么则有:

为最优的预测结果。这里我们希望找到一种线性的形式,还需要使用一些单调变换保证预测值在之间。因此,我们对于每个分类,假设

进一步的,我们取任意类K作为对照组,且各组相加概率之和必为1,所以有:

所以,最终得到两组之间的概率比值为:

最后求解的时候,就是直接用最大似然准则,来求解

这个最大似然函数计算起来比较麻烦,通常很多是数值解。下面以为例,来展示求解过程。

首先我们这个时候有两类,不妨记作1和0,则

则它的对数似然函数:

然后我们求导可得:

之后可以用牛顿法迭代求数值解:

其中二阶导数部分可以化简为:

经过简化之后,这里相当于加权的最小二乘法,目标函数为

所以整个算法可以写作:

0. 令或任意起始值

1. 计算矩阵.

2. 新的.

3. 重复1,2步直至收敛。

这类方法成为IRLS(不断重写的加权最小二乘法)。

LDA和logit选择

其实也没什么定论,两者均为线性,只是一般我们认为LDA需要假设联合正态且方差相等,比较强;而logit假设没有这么强,相比而言更稳定。

perceptional分类器

perceptional分类器是一类相对简单的分类算法,以两类场合为例。为了方便起见,我们假设两类为1和-1,则目标是找出一条直线可以完全分割出来两群点。这里转化成数学的语言,就是找到W使得

或者简化为:

算法也很简单:

1. 给定任意的W值,比如0. 如果,出错。

2. 令新的,重复第一步。

这里可证一个定理:如果原数据集是线性可分的(即W存在),那么在有限步内perceptional算法收敛。其实从第二步可以看出,这样的改进总是趋近于目标的:,一定是在逐步增加的。

同样的算法推广到多累场合,我们就需要引入特征向量,使得条件概率。这样我们的目标就是找到使得

同样的,从0开始,当时,,直至收敛。

不过有意思的是,实践证明,最后使用训练过程中的的平均值效果会更好,而不是最终的值。

--------笔记结束,废话开始--------

到这里,分类器吴老师已经介绍了三类:LDA,Logit和perceptional。其实我一直觉得比较好玩的是分类器和聚类方法的对比——虽然一个是有监督,一个是无监督的学习,不过有的时候我们就算有的观测值也不一定直接就去用——聚类方法某种程度上显得更加自然一些。这也是大家把模型与实际业务相结合起来的成果吧,总要更符合业务上的直觉才可以。是自然的展现群落的形态,还是给定一些条条框框只是去预测?实践中真的是,都去试试才知道那种更符合一个具体案例的需求。这也是在industry玩的比较开心的缘故,没有那么多条条框框,没有那么多“约定俗成“的规矩,需要自己去一步步挖掘这些算法的用武之地。看着一个个自己熟悉或者陌生的模型被逐渐的改造和应用,也是一件蛮开心的事情呢。

Categories
网络新发现

又来用数字挑逗民意

昨晚看到一篇广为流传的房奴文章,比如网易上转载的,实在是让我忍无可忍,决定抄起笔来对付一下这种用数字挑逗民意的行为。真受不了~~~

首先这类文章都会有一个很鲜亮的标题,比如这里的“三代房奴面面观:一代赚满 80后才是真正房奴”。房奴,80后,这两个词加起来就够吸引眼球了,还有“三代”,真的是三代通杀。其实我也没资格批评别人,前段时间写个SAS笔记还搞个“七天搞定SAS”这种噱头,明显动机不纯。

不过题目吸引人也就罢了,正文读下来八成要让人义愤填膺一番。感觉自从今年春天借给松鼠会做讲座的机会,看了一眼现在的新闻之后,就对各种挑逗的方法有了更强的免疫力。

挑逗民意最最典型手段就是以“个例”代替群体。这句话怎么说呢,其实就是不断的举出各种极端的例子。比如这篇文章,对于三代人,各找了一个代表:

70后:于先生

-年龄:35岁

-职业:某金融行业公司品牌策划室经理

-房产:南三环外丰台西马厂区域两居

-2007年购买时单价:6500元/平方米

-2012年该项目二手房单价:约29000元/平方米

35岁的于先生说,目前为止,自己还是一名房奴,但相比2007年买房那会儿,已经轻松和洒脱多了。

80后:陈女士

-年龄:31岁

-职业:广告公关公司合伙人

-房产:东城区富贵园

-2006年购买时单价:10000元/平方米

-2012年该项目二手房单价:38000元/平方米

我就看不大明白了,明明两个人才差了4岁,购房也只差了1年,怎么就被归为两代人的代表了?两个人的故事也没什么大的差别嘛,房价都翻了三四翻的样子。这两个其实还好,最让我看不下去的就是最后一个90后的例子:

90后房奴:生活乐趣才是王道

-人物:赵悦

-年龄:22岁

-职业:资产管理公司销售

-房产:朝阳区小悦城

-2012年4月购买时单价:37000元/平方米

-2012年该项目二手房单价:38000元/平方米

将90后这一代称作房奴可能并不准确,他们中的大多数人刚刚念完大学,但已有不少人也挤进了买房大军。但相对于80后的不堪重负,90后房奴更加轻松,从来就没觉得这是他自己需要承担的。

赵悦是一个重庆姑娘,2011年在英国念完书便来到了北京,父亲是重庆一家国有企业的老总,靠着父亲的关系,她很容易就在北京一家资产管理公司找了一份工作,每月薪酬将近8000元。

赵悦告诉记者,回国没几个月,家里就掏钱给她在朝阳的小悦城买了一个小公寓。这个楼盘位于朝青路上,距离年轻人扎堆的大悦城只有800米,那里聚集着优衣库、H&M等潮店,还有天天人满为患的各种麻辣香锅。“买这房子主要还是因为公寓不限购,而且一个人住也够了。”

赵悦选中商住两用的公寓不在限购范围之内。按照当时的房价,40平米的loft,单价38000元左右,一套房子150多万,不过这样的产权只有40年。“我其实对房子并没有感觉,从来也没觉得回国之后就要买房子,是父母觉得应该有个固定的房子。”

家里为她付了8成首付,只是象征性地贷了一点款,这是因为父母不希望赵悦花钱“月月光”。现在,赵悦每个月要还2000多块钱房贷,这一还款额在北京这样一个城市并不高。但即便是这样,赵悦还是觉得钱不够花。看看赵悦的生活账单,几乎80%钱用在了娱乐消费上,而她自己永远都不太清楚钱到底花到哪里去了。

由于小悦城还没有交房,赵悦在离金融街不远的官园租了一套精装一居室,房租5000元。这里几乎成了金融街的后花园,聚集了大量在金融街上班的小白领。如果全靠赵悦的工资,8000的工资交完房贷、房租,就剩下不到1000了,这点钱还不够她打车的。

赵悦父亲对她比较严厉,但她母亲则更宠爱她,直接给她交了一年的房租,即便这样,赵悦还是寅吃卯粮,经常刷爆信用卡,母亲经常替她还款,还时不时地暗中接济她一些零花钱。

对于国人热衷的房子,赵悦觉得有些不可思议。她自己数了一下,父母的房子、爷爷奶奶的房子加上购买的小公寓,在北京、重庆总计有六套房子。“我都不明白还不够么,我没法理解大家为什么这么热衷于买房子。然后把所有的钱都用来还月供,而每天的日子都过得惨兮兮。”

看看这些数字: 月收入8000(不算低),房租5000,贷款首付80%...一个个都是让人瞠目结舌的数字。通篇下来,90后被描述成了一个彻头彻尾的啃老族和富二代。可是,我们都知道,举例是最常用的论述方法,可是也不能总找最极端的例子吧?田忌赛马的道理大家都知道,总不能拿最差的和最好的比吧?

只是想问几个问题: 70、80后就没有月光和啃老族了么?70、80后在20出头的时候(现在90后的年纪)就不会寅吃卯粮么?拿70后的经理和80后的合伙人,跟一个90后的小销售比,这样公平么?

好好的文章,就从来不能保持客观。相比而言,有时候我觉得CCTV的新闻采访靠谱多了...纵是这样大家都在不停的咒骂。哎,新闻什么时候能保持中立性呢?

Categories
日常应用

七天搞定SAS(七):常用统计模型

本系列连载文章:

其实最后一天,反而是任务最繁重的。这一天,需要纵览SAS的各个常用的统计模块。BTW,在用惯了ggplot2之后,再也不认为有任何理由用其他软件画图了...所以SAS的图形模块自动被我无视(貌似很多SAS用户也一直在吐槽这东西着实不好使)。

SAS里面的概要统计:PROC MEANS

其实前几天也说过了PROC MEANS,不过这里稍稍补充一点置信区间的东西吧。其实它的参数真的挺多的:

    • CLM:双侧置信区间
    • CSS:调整平方和
    • CV:变异系数
    • KURTOSIS:峰度
    • LCLM :单侧置信区间——左侧
    • MAX:最大值
    • MEAN:均值
    • MIN:最小值
    • MODE:众数
    • N :非缺失值个数
    • NMISS:缺失值个数
    • MEDIAN(P50):中位数
    • RANGE:范围
    • SKEWNESS:偏度
    • STDDEV:标准差
    • STDERR:均值的标准误
    • SUM:求和
    • SUMWGT:加权求和
    • UCLM:单侧置信区间:右侧
    • USS:未修正的平方和
    • VAR:方差

ode variance

  • PROBT:t统计量对应的p值
  • T:t统计量
  • Q3 (P75):75%分位数,etc.
  • P10:10%分位数,etc.

在调用CLM的时候需要指定ALPHA:

DATA booklengths;
INFILE 'c:\MyRawData\Picbooks.dat';
INPUT NumberOfPages @@;
RUN;
*Produce summary statistics;
PROC MEANS DATA=booklengths N MEAN MEDIAN CLM ALPHA=.10;
TITLE 'Summary of Picture Book Lengths';
RUN;

结果如下:

2013-12-09 15_46_26-The Little SAS Book(Fourth).PDF - Adobe Reader

SAS里面的相关性分析:PROC CORR

虽然correlation一直被各种批判,但是往往在拿到数据的第一步、毫无idea的时候,correlation还是值得一看的参考指标。SAS里面的PROC CORR提供了相应的功能。

PROC CORR DATA = class;
VAR Television Exercise;
WITH Score;
TITLE ’Correlations for Test Scores’;
TITLE2 ’With Hours of Television and Exercise’;
RUN;

SAS的相关性分析结果输出如下:

2013-12-09 15_47_04-The Little SAS Book(Fourth).PDF - Adobe Reader

SAS里面的基本回归分析:PROC REG

类似于R中的lm(),这个实在是没什么好说的了,最基本的最小二乘法。

DATA hits;
INFILE 'c:\MyRawData\Baseball.dat';
INPUT Height Distance @@;
RUN;
* Perform regression analysis;
PROC REG DATA = hits;
MODEL Distance = Height;
TITLE 'Results of Regression Analysis';
RUN;

SAS的输出结果如下:2013-12-09 15_47_46-The Little SAS Book(Fourth).PDF - Adobe Reader

 

包含了回归模型的基本统计量。我们一般更关注的回归系数:

2013-12-09 15_49_16-The Little SAS Book(Fourth).PDF - Adobe Reader

到这里,我的感慨就是:真的很像Stata呀!值得注意的是,REG有很多可选的参数,对于这些参数是干嘛用的,最权威的自然还是SAS官方的文档:http://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#statug_reg_sect007.htm。其实熟悉了SAS的语法和工作模式之后,具体到某个模型还是看官方文档比较舒服。不愧是商业软件啊,文档写的都很专业,有很多模型选择问题其实看看文档就能多少明白一些了。

比如PROC REG的参数就有:

Table 73.1 PROC REG Statement Options
Option Description
Data Set Options
DATA= names a data set to use for the regression
OUTEST= outputs a data set that contains parameter estimates and other
model fit summary statistics
OUTSSCP= outputs a data set that contains sums of squares and crossproducts
COVOUT outputs the covariance matrix for parameter estimates to the
OUTEST= data set
EDF outputs the number of regressors, the error degrees of freedom,
and the model to the OUTEST= data set
OUTSEB outputs standard errors of the parameter estimates to the
OUTEST= data set
OUTSTB outputs standardized parameter estimates to the OUTEST= data
set. Use only with the RIDGE= or PCOMIT= option.
OUTVIF outputs the variance inflation factors to the OUTEST= data set.
Use only with the RIDGE= or PCOMIT= option.
PCOMIT= performs incomplete principal component analysis and outputs
estimates to the OUTEST= data set
PRESS outputs the PRESS statistic to the OUTEST= data set
RIDGE= performs ridge regression analysis and outputs estimates to the
OUTEST= data set
RSQUARE same effect as the EDF option
TABLEOUT outputs standard errors, confidence limits, and associated test
statistics of the parameter estimates to the OUTEST= data set
ODS Graphics Options
PLOTS= produces ODS graphical displays
Traditional Graphics Options
ANNOTATE= specifies an annotation data set
GOUT= specifies the graphics catalog in which graphics output is saved
Display Options
CORR displays correlation matrix for variables listed in MODEL and
VAR statements
SIMPLE displays simple statistics for each variable listed in MODEL and
VAR statements
USCCP displays uncorrected sums of squares and crossproducts matrix
ALL displays all statistics (CORR, SIMPLE, and USSCP)
NOPRINT suppresses output
LINEPRINTER creates plots requested as line printer plot
Other Options
ALPHA= sets significance value for confidence and prediction intervals and tests
SINGULAR= sets criterion for checking for singularity

SAS里面的基本方差分析:PROC ANOVA

方差分析也就不赘述了,其实我感觉没有回归分析更用的普遍...这俩东西某种程度上也是一回事儿,看怎么理解了。

PROC ANOVA DATA = basket;
CLASS Team;
MODEL Height = Team;
MEANS Team / SCHEFFE;
TITLE ”Girls’ Heights on Basketball Teams”;
RUN;

SAS的输出如下:

2013-12-09 15_50_40-The Little SAS Book(Fourth).PDF - Adobe Reader

先是用作分类的变量的基本统计。然后是模型的基本统计:

2013-12-09 15_50_34-The Little SAS Book(Fourth).PDF - Adobe Reader

最后是各个组的分析结果(两两比较,由于指定了SCHEFFE参数):

2013-12-09 15_51_16-The Little SAS Book(Fourth).PDF - Adobe Reader

SAS中的离散被解释变量模型:PROC LOGISTIC和PROC GENMOD

最简单的离散被解释变量模型就是logit了,在SAS里面有直接的PROC LOGISTIC。官方文档在此:http://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#logistic_toc.htm

语法自然是一如既往的简单:

proc logistic;
model y=x1 x2;
run;

结果返回:

The LOGISTIC Procedure

 

Model Information
Data Set WORK.INGOTS
Response Variable (Events) r
Response Variable (Trials) n
Model binary logit
Optimization Technique Fisher's scoring

Number of Observations Read 19
Number of Observations Used 19
Sum of Frequencies Read 387
Sum of Frequencies Used 387

首先自然是模型的统计信息。然后是数据的统计:

Response Profile
Ordered
Value
Binary Outcome Total
Frequency
1 Event 12
2 Nonevent 375

Model Convergence Status
Convergence criterion (GCONV=1E-8) satisfied

然后是假设检验:

Model Fit Statistics
Criterion Intercept
Only
Intercept
and
Covariates
AIC 108.988 103.222
SC 112.947 119.056
-2 Log L 106.988 95.222

Testing Global Null Hypothesis: BETA=0
Test Chi-Square DF Pr > ChiSq
Likelihood Ratio 11.7663 3 0.0082
Score 16.5417 3 0.0009
Wald 13.4588 3 0.0037

最后是参数估计:

Analysis of Maximum Likelihood Estimates
Parameter DF Estimate Standard
Error
Wald
Chi-Square
Pr > ChiSq
Intercept 1 -5.9901 1.6666 12.9182 0.0003
Heat 1 0.0963 0.0471 4.1895 0.0407
Soak 1 0.2996 0.7551 0.1574 0.6916
Heat*Soak 1 -0.00884 0.0253 0.1219 0.7270

而对于泊松模型,则需要PROC GENMOD。我觉得我一一个列出这些模型已经超出了这篇笔记的范围了...所以干脆就改成简单翻译一下各个PROC的主要模型吧。说过了,学习模型不是主要的目的——模型终究不该通过软件来学...虽然SAS的user guide真的还算是比较好的统计学教材呢。

SAS里面的PROC一览

除了上面说到的PROC,SAS当然还有更多强大的模块。我就顺手一一点开看看这些东西都能做什么...

Categories
游来游去

Shanghai, Yesterday Once More

DSC06635
静与动,inside of the Shanghai Art Museum.

昨天,难得的冬日好阳光,约了三五好友打发时光,却也落得中间几个小时的独行时间,沿着南京东路细细的走了走。越走越熟悉,然后恍然大悟原来同样的路,3年前的这个时候也曾步行而过。那是第一次来上海,那是瞻仰大都市风貌的时候,那是还年轻的抱怨着上海公交车好贵的时候...其实真的,只是过了三年而已。很短,却仿若一个世纪的梦一般长。

DSCN4665
第一次来上海,惊叹于路边的咖啡屋...摄于2009年11月。

DSCN4685
印象颇深的LAN[蘭],至今也不知道是不是餐厅。摄于2009年11月。

南京东路还是一如既往的繁华,繁华到不敢轻易的认知那些看起来有些眼熟的店铺。浮生若梦,不知道在这来来往往的游人脚步中,有多少还会再次相逢。还好有相机为伴,索性仿若第一次来到上海,再次以一个纯粹的游客心情来体会这座迷离的城市。不知道是失落,还是充盈。

DSC06559
南京东路的夕阳, Sunset on the East Nanjing Road, Shanghai.

原来记忆中长长的南京东路并不是那么的长,走走便到了人民广场。念及上海美术馆不久之后就要关门谢客了,赶紧冲进去补拍几张照片——由此也可见我的心是多么的不纯粹,根本不是为了看展览而来的,就是为了看一眼这个古典建筑内部的繁华。

DSC06653
背靠背, Side by side, inside of the Shanghai Art Museum.

DSC06647
冷与暖, cold and warm, inside of the Shanghai Art Museum.

经常会不自觉的驻足在熙熙攘攘人群中的书报摊,这些摊贩们对于潮流文化有着超乎异常的敏锐直觉。果不其然,在一堆八卦杂志之中,《丰乳肥臀》就这么风姿卓绝的挤站着。

DSC06582
九江路上的报摊

走累了就会开始找吃的,比如隐藏在南京西路伊势丹下面的鲷鱼烧...真的吃,好好吃!赶上开业特价买一送一,就毫不客气的红豆奶油抹茶三种口味各入手一个。刚出炉的鲷鱼烧外壳脆脆的里面软软的,口感极佳。

DSC06671
鲷鱼烧

DSC06676
满满的一大袋鲷鱼烧

夜晚的迷离自然需要电影的神奇为伴。艾伦伍迪的新片《To Roma with Love》自然成为了不错的选择。只是在正式上映之前,只有在这种小小的咖啡书屋里面可以一睹为快。不过,真的叫这家咖啡书屋有点委屈它了,人家实则是大名鼎鼎的“私人图书馆”。

DSC06686
2666私人图书馆,静安别墅。

有意思的是上次无意路过也顺手拍了一张,一白一黑,还是蛮有情调来对比看看的。

DSC06688
Day and night, 2666 private library, Jing'an House.

还有一些总是能无意挖掘的神秘地盘,比如这座夜色中的城堡。

DSC06539
人民公园内的餐厅,inside of the Renmin Park at night.

大概是私人的狂欢之所吧,正巧碰到三位婀娜多姿的青年女孩携手走进去。不敢贪恋她们的背影,只有稍稍记录一下这曲径的神秘。

DSC06543
通往狂欢的曲径,Roda towards the restaurant, inside of the Renmin Park, Shanghai.

Yesterday once more, 但也不尽那么的相同一致。在不同的时间,相同的地点,记录下不同或者相同的画面。却也是人生颇有意思的一件事儿。至少,可以在越来越觉年老体衰之时,打发一下时间吧。总觉得陷入回忆是不好的,可是难得回忆如此温馨。

Categories
日常应用

七天搞定SAS(六):宏的编写、程序调错

本系列连载文章:

在SAS各种繁杂的PROC之后,还要来看看MACRO才可以嘛。又不能写函数...

SAS中的MACRO:宏编写

MACRO主要是DO和%LET的各种组合,前者负责循环后者负责变量。

一个例子:

%LET flowertype = Ginger;
* Read the data and subset with a macro variable;
DATA flowersales;
INFILE 'c:\MyRawData\TropicalSales.dat';
INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
IF Variety = "&flowertype";
RUN;
* Print the report using a macro variable;
PROC PRINT DATA = flowersales;
FORMAT SaleDate WORDDATE18.;
TITLE "Sales of &flowertype";
RUN;

这段代码可以做什么呢?很简单,替换文字。我们指定了一个SAS MACRO中的变量flowertype,在执行MACRO的时候他会被自动翻译成标准的SAS代码。这样执行的结果就是:

2013-12-09 15_57_22-The Little SAS Book(Fourth).PDF - Adobe Reader

看到了吧,标题已经被替换了。

一段MACRO以%macro开始,然后以%mend结束。

* Macro to print 5 largest sales;
%MACRO sample;
PROC SORT DATA = flowersales;
BY DESCENDING Quantity;
RUN;
PROC PRINT DATA = flowersales (OBS = 5);
FORMAT SaleDate WORDDATE18.;
TITLE 'Five Largest Sales';
RUN;
%MEND sample;
* Read the flower sales data;
DATA flowersales;
INFILE 'c:\MyRawData\TropicalSales.dat';
INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
RUN;
* Invoke the macro;
%sample

这样执行之后的结果就是:

2013-12-09 15_58_09-The Little SAS Book(Fourth).PDF - Adobe Reader

虽然SAS不可以直接写函数,但是MACRO还是有参数可以传入的。

* Macro with parameters;
%MACRO select(customer=,sortvar=);
PROC SORT DATA = flowersales OUT = salesout;
BY &sortvar;
WHERE CustomerID = "&customer";
RUN;
PROC PRINT DATA = salesout;
FORMAT SaleDate WORDDATE18.;
TITLE1 "Orders for Customer Number &customer";
TITLE2 "Sorted by &sortvar";
RUN;
%MEND select;
* Read all the flower sales data;
DATA flowersales;
INFILE 'c:\MyRawData\TropicalSales.dat';
INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
RUN;
*Invoke the macro;
%select(customer = 356W, sortvar = Quantity)
%select(customer = 240W, sortvar = Variety)

这样传入的参数会自动作为变量被替换掉。结果如下:

2013-12-09 15_59_26-The Little SAS Book(Fourth).PDF - Adobe Reader

当然MACRO中也会有需要判断的时候,这就是IF上场之时啦:

%MACRO dailyreports;
%IF &SYSDAY = Monday %THEN %DO;
PROC PRINT DATA = flowersales;
FORMAT SaleDate WORDDATE18.;
TITLE 'Monday Report: Current Flower Sales';
RUN;
%END;
%ELSE %IF &SYSDAY = Tuesday %THEN %DO;
PROC MEANS DATA = flowersales MEAN MIN MAX;
CLASS Variety;
VAR Quantity;
TITLE 'Tuesday Report: Summary of Flower Sales';
RUN;
%END;
%MEND dailyreports;
DATA flowersales;
INFILE 'c:\MyRawData\TropicalSales.dat';
INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
RUN;
%dailyreports

比如周二,那么翻译出来的SAS代码就是:

DATA flowersales;
INFILE 'c:\MyRawData\TropicalSales.dat';
INPUT CustomerID $ @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
RUN;
PROC MEANS DATA = flowersales MEAN MIN MAX;
CLASS Variety;
VAR Quantity;
TITLE 'Tuesday Report: Summary of Flower Sales';
RUN;

最终得到的结果为:
2013-12-09 16_00_55-The Little SAS Book(Fourth).PDF - Adobe Reader

SAS中使用CALL SYMPUT:用数据值赋予变量

如果有的时候需要数据集中的值来给MACRO中的变量赋值,我们就需要使用CALL SYMPUT了。

* Read the raw data;
DATA flowersales;
INFILE 'c:\MySASLib\TropicalSales.dat';
INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity;
PROC SORT DATA = flowersales;
BY DESCENDING Quantity;
RUN;
* Find biggest order and pass the customer id to a macro variable;
DATA _NULL_;
SET flowersales;
IF _N_ = 1 THEN CALL SYMPUT("selectedcustomer",CustomerID);
ELSE STOP;
RUN;
PROC PRINT DATA = flowersales;
WHERE CustomerID = "&selectedcustomer";
FORMAT SaleDate WORDDATE18.;
TITLE "Customer &selectedcustomer Had the Single Largest Order";
RUN;

这样的结果就成了:

2013-12-09 16_01_50-The Little SAS Book(Fourth).PDF - Adobe Reader

看出来这里面的逻辑了么?我们先对数据集flowersales进行了排序,然后选择第一名的订单用户,赋值给selectedcustomer这个变量,然后就可以直接在后面用&selectedcustomer调用这个变量值,去查找属于他的观测记录了。

SAS MACRO的DEBUG调试

这里就是一些基本的找错技巧了:

  • 避免最常见的语法错误:先写一般的SAS语句,然后去替换需要用到变量的部分。
  • 引号问题:如果用单引号,那么SAS不会替换里面的变量值;如果用双引号,那么里面&variable的值会被替换掉。所以酌情注意。
  • SAS的报错记录:有MERROR(找不到macro)、SERROR(找不到变量)、MLOGIC(SAS将在日志中输出详细的执行情况)、MPRINT(SAS将在日志中输出翻译出来的SAS代码)、SYMBOLGEN(SAS将在日志中输出变量当时的赋值)。

SAS常见程序错误

最常见的大概就是少了结尾的分号...这里的报错一般是:

ERROR 180-322: Statement is not valid or it is used out of proper order.

或者其他类似的语句无法被SAS理解的。

还有就是输入数据不正确或者有缺失值什么的...这个我觉得在数据源是数据库管理系统的时候,不是什么问题...

还有就是数值型被转换成文本型...报错类似于:

NOTE: Character values have been converted to numeric values at the places
given by:(Line):(Column).

我们利用PUTLOG可以一步步的输出SAS计算的过程:

9 * Keep only students with mean below 70;
10 DATA lowscore;
11 INFILE ’c:MyRawDataClass.dat’;
12 INPUT Name $ Score1 Score2 Score3 Homework;
13 Homework = Homework * 2;
14 AverageScore = MEAN(Score1 + Score2 + Score3 + Homework);
15 PUTLOG Name= Score1= Score2= Score3= Homework= AverageScore=;
16 IF AverageScore < 70;
17 RUN;

这样也有利于查错。

其他的可以直接看报错信息来判断,不赘述了。