坚强别无选择 发表于 2019-9-19 14:34:20

SAS程序统计方法剔除无关变量


/**定义SAS逻辑库mydata,对应于E:\dm目录**/
libname mydata "E:\dm";

/** 读入数据,生成SAS数据集mydata.Credit **/
proc import datafile="E:\data\ch2_credit.csv"
out=mydata.Credit dbms=DLM;
/*将数据从Credit.csv文件读入,存储在SAS逻辑库mydata下的数据集Credit中;
    dbms指定读入数据的种类,DLM说明数据是带分隔符的*/
delimiter=',';
/*说明分隔符是逗号(缺省分隔符为空格)*/
getnames=yes;
/*需要从第一行读入变量名*/
run;
proc print data=mydata.Credit(obs=5);
run;

/**为数据集中的某些变量添加标签,说明变量的具体含义**/
data mydata.Credit;
set mydata.Credit;
label age_inferr="inferred age"
      /*推断出的年龄*/
      dob_month="Date of Birth (Month)"
      /*出生月份*/
      dob_year="Date of Birth (Year)"
      /*出生年*/
      buyer_p_="Target: response indicator"
      /*是否响应(因变量)*/
      sex="Gender of the applicant"
      /*性别*/
      married="Marriage status of the applicant"
      /*婚姻状况*/
      children="the indicator for whether having children"
      /*是否有孩子*/
      own_home="the indicator for owning home (vs renting)";
      /*是否拥有(而不是租赁)住房*/
run;


/**对数据集进行基本描述**/
proc contents data=mydata.Credit out=a0 noprint;
/*被描述的数据集为mydata.Credit,描述结果存入SAS数据集work.a0,
    noprint选项说明不在屏幕上打印描述结果*/
run;

/**定义计算各数值变量描述统计量的宏函数**/
%macro nvardescrip(data=,out=);
/*"%macro"是SAS中的宏语句,说明下面要定义一个宏函数;
宏函数名称为nvardescrip,参数data指定用于描述的输入数据集,
参数out指定存储统计描述结果的输出数据集*/

/**得到输入数据集&data(引用参数data的值)的基本描述**/
proc contents data=&data out=a0 noprint;
run;

/**创建宏变量记录输入数据集中所有数值变量的名称**/
proc sql;
    select NAME into :nvars separated by ' ' from a0
    where TYPE=1;
    /*nvars是创建的宏变量的名称,它的取值是一个字符串,由所有数值变量
   (work.a0中TYPE取值为1)的名称(work.a0中的NAME)以空格分隔连接而成*/
quit;

%let i=1;
/*"%let"是SAS中的宏语句,此处定义宏变量i并赋予其初始值1*/
%do %until (%scan(&nvars,&i,' ')=);
/*"%do %until (条件)"是SAS中的宏语句,说明持续进行循环直到后面的条件为真。
    "scan"是SAS自带的宏函数,SAS中调用宏函数都需要加上"%"。
      该宏函数的第一个参数指定需要扫描的字符串,第二个参数指定
      从被扫描的字符串中提取第几段,第三个参数指定被扫描的字符串中
      各段之间的分隔符。
    总而言之,这条语句的意思是循环执行下面的操作,直到宏变量nvars所指
      的字符串中以空格分隔的第i段(也就是第i个数值变量的名称)为空;
      宏变量i的值在每次循环结束后将递增1,因此这条语句就是说对输入数据集
      的每个数值变量执行下面的操作*/

    %let varname=%scan(&nvars,&i,' ');
    /*定义宏变量varname存储宏变量nvars所指的字符串中以空格分隔的第i段,
      即第i个数值变量的名称*/

    proc univariate data=&data noprint;
      var &varname;
      /*使用UNIVARIATE过程对输入数据集&data的当前数值变量(其名称存储于
      宏变量varname)进行描述,noprint选项说明描述结果不在屏幕上打印*/
      output out=a1 nmiss=nmiss mean=mean std=std min=min Q1=Q1
             median=median Q3=Q3 max=max;
      /*输出数据集为work.a1,其中只有一行,记录了变量的缺失观测数、
      均值、标准偏差、最小值、下四分位数、中位数、上四分位数、最大值;
      例如,mean=mean中,前一个mean是UNIVARIATE过程的关键字,说明要
      计算变量的均值,后一个mean是work.a1中记录该均值的变量名*/
    run;

    data a1;
      retain name nmiss mean std min Q1 median Q3 max;
      /*指定work.a1中各变量的顺序*/
      set a1;
      length name $15.;
      /*在数据集work.a1中产生新变量name,格式是长度为15的字符串*/
      name="&varname";
      /*变量name的取值是当前数值变量的名称(即宏变量varname所存储的值)*/
      label name="变量名"
            nmiss="缺失观测数" mean="均值"
            std="标准偏差" min="最小值"
            Q1="下四分位数" median="中位数"
            Q3="上四分位数" max="最大值" ;
      /*给work.a1中各变量添加标签*/
    run;

    %if &i=1 %then %do;
    /*"%if (条件) %then %do"是SAS中的宏语句,说明如果条件为真,
      执行如下操作。此处条件是宏变量i的值为1,即当前数值变量是
      输入数据集中第一个数值变量*/
      data &out;
      set a1;
      /*将work.a1拷贝给用于记录所有数值变量的描述统计量的输出数据集&out*/
      run;
    %end;
    /*"%end"与前面"%if &i=1 %then %do"中的"%do"配对,结束这一段操作*/

    %else %do;
    /*"%else %do"是SAS中的宏语句,与"%if (条件) %then %do"语句配合,
      说明如果条件不为真,执行如下操作*/
      proc append base=&out data=a1;
      /*将work.a1的数据添加在输出数据集&out的现有数据之后*/
      run;
    %end;
    /*"%end"与前面"%else %do"中的"%do"配对,结束这一段操作*/

    %let i=%eval(&i+1);
    /*在每次循环结束处,让i值递增1,以便对下一个数值变量进行描述。
      注意:i是宏变量,使用"&i"只会直接引用i的值,而不会进行计算。
      所以如果i存储的值是1,那么使用"%let i=&i+1"语句只会让i的值
      变成字符串"1+1",而不会变成2;因此需要使用SAS自带的宏函数eval
      来进行计算。*/
%end;
/*与前面的"%do %until"对应,结束整个循环*/

%mend;
/*结束宏函数nvardescrip的定义*/

/**调用宏函数nvardescrip计算mydata.Credit中各数值变量的描述统计量**/
%nvardescrip(data=mydata.Credit,out=mydata.Credit_nvars_description);

/**定义画各数值变量直方图的宏函数**/
%macro histogram(data=,pdfout="histogram.pdf");
/*定义宏函数histogram,参数data指定用于画直方图的输入数据集,
参数pdfout指定输出的pdf文件的名称,缺省文件名为histogram.pdf。*/

proc contents data=&data out=a0 noprint;
run;

proc sql;
    select NAME into :nvars separated by ' ' from a0
    where TYPE=1;
quit;

ods listing exclude all;
/*ods(Output Delivery System)是SAS的输出传递系统,
    listing是缺省的输出窗口,"exclude all"表明所有输出都不导向listing*/
ods pdf file=&pdfout;
/*将输出导向到pdf文件,文件名由宏变量pdfout指定*/

%let i=1;
%do %until (%scan(&nvars,&i,' ')=);

    %let varname=%scan(&nvars,&i,' ');

    title1 &varname;
    /*使用当前数值变量的名称作为直方图的标题*/
    proc univariate data=&data noprint;
      histogram &varname / cbarline=grey cfill=ligr;
      /*histogram语句说明要对当前数值变量画直方图;
      "cbarline=grey"指定直方图中各柱用灰色勾勒边线,
      "cfill=ligr"指定直方图中各柱用浅灰色填充。*/
      inset n nmiss mean std min Q1 median Q3 max /
          header='Descriptive Statistics' pos=ne noframe;
      /*在图的右上方(即pos关键字指定的ne,代表northeast即东北方)
          插入统计量表,表头为"Descriptive Statistics",含有观测数(n)、
          缺失观测数(nmiss)、均值(mean)、标准偏差(std)、最小值(min)、
          下四分位数(Q1)、中位数(median)、上四分位数(Q3)、最大值(max)
          等统计量,noframe指明该表没有边框 */
    run;

    %let i=%eval(&i+1);
%end;

ods pdf close;
/*关闭pdf输出环境*/
ods listing exclude none;
/*将所有输出重新导向到listing*/

%mend;
/*结束宏函数histogram的定义*/

/**调用宏函数histogram画mydata.Credit中各数值变量的直方图**/
%histogram(data=mydata.Credit,pdfout="E:\dm\ch2_case2-2_histogram.pdf");

data mydata.CreditNew;
/*生成新数据集mydata.CreditNew,在其上进行数据的修改*/
set mydata.Credit;
drop criteria own_home;
run;

data mydata.CreditNew;
set mydata.CreditNew;
bcbal1=log(bcbal+1);
/*对数转换*/
run;

proc rank data=mydata.CreditNew out=mydata.CreditNew groups=100;
/*秩转换,"group=100"指定以百分位数将数据分隔为组,
转换后变量的取值为0至99*/
var bcbal;
ranks bcbal2;
/*对原始变量bcbal进行秩转换,记录转换后数值的变量的名称为bcbal2*/
run;

proc freq data=mydata.Credit;
table sex;
run;

proc ttest data=mydata.Credit;
class buyer_p_;
var age_inferr;
run;

proc freq data=mydata.Credit;
tables buyer_p_*sex / chisq;
run;

/**将所有响应者的数据放入work.credit1数据集中**/
data credit1;
set mydata.CreditNew;
where BUYER_P_=1;
run;

/**将所有非响应者的数据放入work.credit0数据集中**/
data credit0;
set mydata.CreditNew;
where BUYER_P_=0;
run;

/**创建宏变量n1记录响应者的观测数**/
proc sql noprint;
select count(*) into :n1 from credit1;
quit;

/**创建宏变量n0记录非响应者的观测数,它的值是响应者观测数n1的两倍**/
%let n0=%eval(2*&n1);

/**从非响应者的数据中随机抽取n0个观测,仍然放入work.credit0数据集中**/
proc surveyselect data=credit0 method=srs
/*"method=srs"说明抽样方法是简单随机抽样(simple random sampling)*/
n=&n0 out=credit0;
run;

/**将响应者和非响应者的数据都放入mydata.CreditNew1数据集中**/
data mydata.CreditNew1;
set credit1 credit0;
run;



页: [1]
查看完整版本: SAS程序统计方法剔除无关变量