资源描述
一、会计研究中的STATA运用 - Clive Lennox的个人网站http://ihome.ust.hk/~accl/Phd_teaching.htm - 为中山大学会计系所授课程 · 课件和演示用数据
二、高惠璇等编译,SAS系统 BASE SAS软件使用手册,中国统计出版社,1997;
• 高惠璇等编译,SAS系统 SAS/STAT软件使用手册,中国统计出版社,1997;
• 这两本书类似于字典,用来查,而不是用来读;
三、将EXCEL数据导入SAS
比如,要将H盘SAS目录中的profit.xls文件导入SAS,并命名为profit;
打开SAS,在编辑器中写入程序:
proc import out=profit datafile="H:\SAS\profit.xls"
dbms=excel2000 replace;
run;
结果:在SAS逻辑库的Work中,就会出现profit数据集;
四、右键点开profit数据集查看数据集情况;
• 将Accper转变成年度;
data profit;set profit;
year=substr(accper,1,4)+0; 字符加0直接转换为数字格式。
run;
• 五、数据排序:如果想剔除重复的观测值,可以
• 加nodupkey,noudupkey可省略
•
- 对profit数据按照stkcd和year进行排序;
proc sort data=profit nodupkey;
by stkcd year;
run;
• 变量改名
data profit1;set profit;
rename stkcd=code;
run;
• 六、数据横向合并:在对两个或多个数据集进行merge时,需要首先按照关键变量如公司代码和年度)进行排序;
•
- 比如,要将Profit和solvency进行merge:
先将solvency.xls文件导入SAS
proc import out=solvency datafile=“H:\SAS\solvency.xls"
dbms=excel2000 replace;
run;
data solvency;set solvency;
year=substr(accper,1,4)+0;
run;
proc sort; by stkcd year;run; 省略时,默认对最近的数据集进行排序
data fin_ratio;merge profit(in=a) solvency;
by stkcd year;
if a;
run;
注意:data x1;merge tmp1(in=a) tmp2;by var1 var2;if a;run
- 表示已tmp1为基础进行合并,合并后的数据集样本数同tmp1相同;
data x1;merge tmp1 tmp2;by var1 var2;run
- 包括了tmp1和tmp2的所有观测值;
data x1;merge tmp1(in=a) tmp2(in=b) ;by var1 var2; if a=1 and b=1;run
- 只包括tmp1和tmp2中共有的观测值;
• 七、纵向合并(append)
data x1; set tmp1 tmp2;
Run;
- SAS自己会去找对应的变量;
• 八、产生新的虚拟变量
比如,要从fin_ratio产生一个2006以后的虚拟变量,即年度在2006年后的,取值为1,否则为0; 则:
data fin_ratio;set fin_ratio;
after2006=0; 先对after2006变量赋0值。
if year>=2006 then after2006=1;
run;
• 九、剔除变量空缺的观测值;
• CSMAR数据集中,有些变量空缺,导入SAS为“.”,有些无点,为一个空格,则可以通过如下命令剔除这些数据缺失的观测值:
- 比如,希望剔除fin_ratio数据中,ROS缺失的样本;
proc sort data=fin_ratio;by ros;run;
data tmp1;set fin_ratio;
if ros=. or ros=" " then delete;
run;
假如要把ROS,ROA,ROE的缺失样本同时删除:
data tmp2;set fin_ratio;
if ros+roa+roe=. then delete;
run;
SAS的一些基本算符:
+ - * / = 等于 ~= 不等于
> >= < <=
SAS的函数分类可以参见高惠璇SAS BASE 1997 pp.70-74
• 十、SAS日期函数
• 在CSMAR的数据库中,导出的日期文件一般为yyyy-mm-dd,如1999-12-31日,这是一个文本格式,那么,如何将其转化为标准的日期格式呢?
• 比如,我们经常要计算公司上市年龄,上市公司年龄等于各个财政年度末减去IPO日期所间隔的天数,然后除于365得到上市年龄,比如,一个公司1995-05-23日IPO,则2007年12月31日时,他的上市年龄多少?
- SAS日期值函数:Mdy(month,day,year);
如mdy(12,31,1991)=11687,11687代表1991-12-31日同1960-1-1所间隔的天数;
- 还原出sas日期值的函数:
假定date是一个SAS日期值,则year(date)得到年,month(date)得到月,day(date)得到日;
- 现在,我们要计算Fin_ratio数据集中,各公司财政年末同1990-05-07(假定所有公司IPO日期都是这天)的时间距离;
data tmp1;set fin_ratio(keep=stkcd accper ros);
ipodate=mdy(5,7,1990);
run;
data tmp2;set tmp1;
fiscal_year=substr(accper,1,4)+0;
fiscal_month=substr(accper,6,2)+0;
fiscal_day=substr(accper,9,2)+0;
fiscaldate=mdy(fiscal_month,fiscal_day,fiscal_year);
age=(fiscaldate-ipodate)/365;
run;
• 十一、对数据进行winsorize处理:Winsorize的原理:如果一个样本某变量的值大于该变量的99分位数,则该样本的值被强制指定为99分位数的值;类似的,如果一个样本某变量的值小于该变量的1分位数,则该样本该变量的值被强制指定为1分位数的值;
• 任务:对fin_ratio中的ROS,ROE,ROA,Current和Acid按上下1%进行winsorize处理;
• Proc means: 对数据进行描述性统计;noprint: 统计结果不在SAS中显示;
• Var: 指定需要分析的变量;
• by: 按什么条件进行分析(e.g., by year , 分年度进行分析);
• Output out=tmp2: 将分析结果保存于tmp2中;
• p1:变量1分位数的值 p1=x1-x5: 5个变量1分位数的值(-不是减号);
• p99: 变量99分位数的值;
•
data tmp1;set fin_ratio; d=1;run;
proc means noprint;
var roa roe ros current acid;
by d;
output out=tmp2(drop=_freq_ _type_) p1=x1-x5 p99=y1-y5;
data tmp3;
merge tmp1 tmp2; by d;
array z{1:5} roa roe ros current acid;
Array: 指定一组变量(向量);
如这里:z[1]便为roa, x[1]为x1,即roa的1分位数;
y[1]为y1, 即roa99分位数;
由于需要winsorize五个变量,因此需要循环5次;
array x{1:5} x1-x5;array y{1:5} y1-y5;
do i=1 to 5;
if z[i]<x[i] and z[i]~=. then z[i]=x[i];
if z[i]>y[i] then z[i]=y[i];
end;drop i d x1-x5 y1-y5;
run;
• 十二、希望对一组样本进行描述性统计,包括均值、中位数、标准差等,可以采用proc means 和proc univariate模块;
• 比如,希望对fin_ratio进行描述性统计:
proc means data=fin_ratio;
var roa roe ros current acid after2006;
run;
• 如果希望按年度或按行业分组进行描述性统计:
proc sort data=fin_ratio;
by year indcd;run;
proc means data=fin_ratio;
var roa roe ros current acid after2006;
by year indcd;
run;
• 十三、如果希望保存每组样本的某个统计量(如均值,中位数或者标准差),则可以使用如下程序:
• 比如,希望计算1990-2006年按年和行业均值(中位数)调整后的ROA和ROS,则程序如下:
*由于indcd行业分类太细,我们只想使用22个行业,即C类分到二级代码,其余都使用一级代码
data tmp1;set fin_ratio(keep=stkcd year indcd roa ros);
if substr(indcd,1,1)="C" then ind=substr(indcd,1,2);
if substr(indcd,1,1)~="C" then ind=substr(indcd,1,1);
drop indcd;
run;
产生各年、各行业ROA和ROS的均值和中位数;
proc sort data=tmp1;by year ind;run;
proc means noprint;
var roa ros;
by year ind;
output out=tmp2 mean=mean_roa mean_ros median=median_roa median_ros;
run;
合并tm1和tmp2,以计算均值\中位数调整后的roa和ros;
data tmp3;merge tmp1 tmp2;
by year ind;
run;
data tmp4;set tmp3;
roa_mean_adj=roa-mean_roa;
roa_median_adj=roa-median_roa;
ros_mean_adj=ros-mean_ros;
ros_median_adj=ros-median_ros;
run;
十四、如果还想看看样本更全面的统计变量,可以使用proc univariate命令,这个命令还可以顺带检验样本的均值(中位数)是否异于0;
proc univariate data=fin_ratio;
var ros roa;
run;
十五、CAR的计算程序:
(一) 理论依据:
在事件研究(event study)中,计算累计非正常报酬(CAR)是个常见问题;两种计算CAR的方法:参考文献: Chen, Su and Zhao, 2000, CAR;
1、市场均值调整: 事件日的个股回报减去当天的市场回报;
2、市场调整法: 首先要估算个股的Beta系数,然后根据CAMP模型计算事件日的CAR;
十六、查找重复记录并删除
(1)、查找重复的记录数(转载自
data b;
input id $ a b c;
cards;
001 1 2 20
002 2 3 18
003 3 4 35
004 4 5 40
002 2 3 27
006 5 6 40
004 4 5 60
;
run;
proc summary data=b nway;
class id a b;
output out=c (drop=_type_ where=(_freq_>1));
run;
proc print data=c;
run;
结果如下:
Obs id a b _FREQ_
1 002 2 3 2
2 004 4 5 2
(2)核查后剔除重复的记录数(转载自
仍采用上述例子
proc sort data=b nodupkey out=d;
by id a b;
run;
proc print data=d;
run;
结果:
Obs id a b c
1 001 1 2 20
2 002 2 3 18
3 003 3 4 35
4 004 4 5 40
5 006 5 6 40
十七、分组后的第一条记录和最后一条记录
data tmp2; set tmp2;
by stkcd;
if first.stkcd then tqa=.;
if last.stkcd then tqb=.;
run;
展开阅读全文