WYY's Blog

JUST DO IT


  • Home

  • About

  • Tags

  • Categories

  • Archives

Numpy Basics

Posted on 2017-09-14 | In Data Analysis

Numpy Basics: Arrays and Vectorized Computation

Magic Methods

Command Description
%quickref Display the IPython Quick Reference Card
%magic Display detailed documentation for all of the available magic commands
%debug Enter the interactive debugger at the bottom of the last exception traceback
%hist Print command input (and optionally output) history
%pdb Automatically enter debugger after any exception
%paste Execute preformatted Python code from clipboard
%cpaste Open a special prompt for manually pasting Python code to be executed
%reset Delete all variables/names defined in interactive namespace
%page OBJECT Pretty-print the object and display it through a pager
%run script.py Run a Python script inside IPython
%prun statement Execute statement with cProfile and report the profiler output
%time statement Report the execution time of a single statement
%timeit statement Run a statement multiple times to compute an ensemble average execution time; useful for timing code with very short execution time
%who, %who_ls, %whos Display variables defined in interactive namespace, with varying levels of information/ verbosity
%xdel variable Delete a variable and attempt to clear any references to the object in the IPython internals

Set print options

  • Precision
1
2
3
4
5
6
7
8
9
10
11
In [1]: import numpy as np
In [2]: x = np.random.random(5)
In [3]: x
Out[3]: array([ 0.11528565, 0.50686134, 0.16554924, 0.77585094, 0.99374836])
In [4]: np.set_printoptions(precision=3)
In [5]: x
Out[5]: array([ 0.115, 0.507, 0.166, 0.776, 0.994])
  • Scientific notation
1
2
3
4
5
6
7
8
9
In [6]: y = np.array([1.5e-10, 1.5, 1500])
In [7]: y
Out[7]: array([ 1.500e-10, 1.500e+00, 1.500e+03])
In [8]: np.set_printoptions(suppress=True)
In [9]: y
Out[9]: array([ 0. , 1.5, 1500. ])

Array creation Functions

Function Description
array Convert input data (list, tuple, array, or other sequence type) to an ndarray either by inferring a dtype or explicitly specifying a dtype; copies the input data by default
asarray Convert input to ndarray, but do not copy if the input is already an ndarray
arange Like the built-inrangebut returns an ndarray instead of a list
ones, ones_like Produce an array of all 1s with the given shape and dtype; ones_like takes another array and produces a ones array of the same shape and dtype
zeros, zeros_like Likeonesandones_likebut producing arrays of 0s instead
empty, empty_like Create new arrays by allocating new memory, but do not populate with any values like ones and zeros
full, full_like Produce an array of the given shape and dtype with all values set to the indicated “fill value” full_like takes another array and produces a filled array of the same shape and dtype
eye, identity Create a square N × N identity matrix (1s on the diagonal and 0s elsewhere)

Why choose np.zeros? It’s the Fastest.

1
2
3
4
5
6
7
8
9
10
11
12
13
In [2]: size=100000000
In [3]: %timeit np.full(size, 0)
1 loop, best of 3: 5.41 s per loop
In [4]: %timeit np.zeros(size)
10000 loops, best of 3: 21.8 µs per loop
In [5]: %timeit np.ones(size)
1 loop, best of 3: 5.56 s per loop
In [6]: %timeit a = np.empty(size); a[:]=0
1 loop, best of 3: 5.02 s per loop

Indexing and Slicing

An important first distinction from Python’s built-in lists is that array slices are views on the original array. This means that the data is not copied, and any modifications to the view will be reflected in the source array.

If you want a copy of a slice of an ndarray instead of a view, you will need to explicitly copy the array-for example, array_a[2:4].copy().

1
2
3
4
5
6
7
8
9
In [19]: array_a
Out[19]: array([0, 1, 2, 3, 4, 5, 6])
In [20]: slice_a = array_a[2:4]
In [22]: slice_a[:] = 9
In [23]: array_a
Out[23]: array([0, 1, 9, 9, 4, 5, 6])

Fancy Indexing

Fancy indexing, unlike slicing, always copies the data into a new array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
In [2]: arr = np.arange(32).reshape(8,4)
In [3]: arr
Out[3]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]])
In [4]: arr[[1,5,7,2],[0,3,1,2]]
Out[4]: array([ 4, 23, 29, 10])
In [5]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
Out[5]:
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])

Transposing Arrays and Swapping Axes

  • Transposing is a special form of reshaping that similarly returns a view on the under‐ lying data without copying anything.
  • swapaxes similarly returns a view on the data without making a copy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
In [3]: arr = np.arange(15).reshape(3,5)
In [4]: arr
Out[4]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [5]: arr.T
Out[5]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
In [6]: arr.transpose()
Out[6]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])

How does NumPy’s transpose() method permute the axes of an array?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
In [8]: arr
Out[8]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [9]: arr.transpose((1,0,2))
Out[9]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
In [10]: arr.swapaxes(0,1)
Out[10]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])

Universal Functions

Ufuncs accept an optional out argument that allows them to operate in-place on arrays:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In [33]: arr
Out[33]:
array([-3.503414 , 1.42652472, -1.73331188, -3.46089728, -0.08580737,
3.36266732, -0.80950291])
In [34]: np.sqrt(arr)
Out[34]:
array([ nan, 1.1943721, nan, nan, nan,
1.8337577, nan])
In [35]: np.sqrt(arr,arr)
Out[35]:
array([ nan, 1.1943721, nan, nan, nan,
1.8337577, nan])
In [36]: arr
Out[36]:
array([ nan, 1.1943721, nan, nan, nan,
1.8337577, nan])

Unary ufuncs

Function Description
abs, fabs Compute the absolute value element-wise for integer, floating-point, or complex values. For non-complex values, fabs is faster
sqr Compute the square root of each element (equivalent to arr ** 0.5)
square Compute the square of each element (equivalent to arr ** 2)
Exp Compute the exponent e^x of each element
log, log10, log2, log1p Natural logarithm (base e), log base 10, log base 2, and log(1 + x), respectively
sign Compute the sign of each element: 1 (positive), 0 (zero), or –1 (negative)
ceil Compute the ceiling of each element (i.e., the smallest integer greater than or equal to that number)
floor Compute the floor of each element (i.e., the largest integer less than or equal to each element)
rint Round elements to the nearest integer, preserving the dtype
modf Return fractional and integral parts of array as a separate array
isnan Return boolean array indicating whether each value is NaN (Not a Number)
isfinite, isinf Return boolean array indicating whether each element is finite (non-inf, non-NaN) or infinite, respectively
cos, cosh, sin, sinh, tan, tanh Regular and hyperbolic trigonometric functions
arccos, arccosh, arcsin, arcsinh, arctan, arctanh Inverse trigonometric functions
logical_not Compute truth value of not x element-wise (equivalent to ~arr)

Binary universal functions

Function Description
add Add corresponding elements in arrays
subtract Subtract elements in second array from first array
multiply Multiply array elements
devide, floor_devide Divide or floor divide (truncating the remainder)
power Raise elements in first array to powers indicated in second array
maximum, fmax Element-wise maximum; fmax ignores NaN
minimum, fmin Element-wise minimum; fmin ignores NaN
mod Element-wise modulus (remainder of division)
copysign Copy sign of values in second argument to values in first argument
greater, greater_equal, less, less_equal, equal, not_equal Perform element-wise comparison, yielding boolean array (equivalent to infix operators >, >=, <, <=, ==, !=)
logical_and, logical_or, logical_xor Compute element-wise truth value of logical operation (equivalent to infix operators &\ ,^)

Basic array statistical methods

Function Description
sum Sum of all the elements in the array or along an axis; zero-length arrays have sum 0
mean Arithmetic mean; zero-length arrays have NaN mean
std, var Standard deviation and variance, respectively, with optional degrees of freedom adjustment (default denominator n)
min, max Minimum and maximum
argmin, argmax Indices of minimum and maximum elements, respectively
cumsum Cumulative sum of elements starting from 0
cumprod Cumulative product of elements starting from 1

Array set operations

Function Description
unique(x) Compute the sorted, unique elements in x
intersect1d(x, y) Compute the sorted, common elements in x and y
union1d(x, y) Compute the sorted union of elements
in1d(x, y) Compute a boolean array indicating whether each element of x is contained in y
setdiff1d(x, y) Set difference, elements in x that are not in y
setxor1d(x, y) Set symmetric differences; elements that are in either of the arrays, but not both

Linear Algebra

Function Description
diag Return the diagonal (or off-diagonal) elements of a square matrix as a 1D array, or convert a 1D array into a square matrix with zeros on the off-diagonal
dot Matrix multiplication
trace Compute the sum of the diagonal elements
det Compute the matrix determinant
eig Compute the eigenvalues and eigenvectors of a square matrix
inv Compute the inverse of a square matrix
pinv Compute the Moore-Penrose pseudo-inverse of a matrix
qr Compute the QR decomposition
svd Compute the singular value decomposition (SVD)
solve Solve the linear system Ax = b for x, where A is a square matrix
lstsq Compute the least-squares solution to Ax = b

Pseudorandom Number Generation

Function Description
seed Seed the random number generator
permutation Return a random permutation of a sequence, or return a permuted range
shuffle Randomly permute a sequence in-place
rand Draw samples from a uniform distribution
randint Draw random integers from a given low-to-high range
randn Draw samples from a normal distribution with mean 0 and standard deviation 1
binomial Draw samples from a binomial distribution
normal Draw samples from a normal (Gaussian) distribution
beta Draw samples from a beta distribution
chisquare Draw samples from a chi-square distribution
gamma Draw samples from a gamma distribution
uniform Draw samples from a uniform [0, 1) distribution

《SAS编程演义》笔记(8章)

Posted on 2017-09-13 | In SAS

菱花荇蔓随双桨:百变绘图

ODS Graphics System

  • ODS Graphics System的语法简介统一,易于学习
  • ODS Graphics System已包含在BASE模块中,不像GRAPH还要单独购买

ODS Graphics System的五大部件:

  • ODS Graphics 语句
    • 通过ON或OFF开关启用ODS Graphics
    • 通过统计过程选项PLOTS选项创建ODS Graphics
    • 通过BRODER、WIDTH、HEIGHT、OUTPUTFMT、IMAGENAME等控制边框、宽、高、输出格式、以及图片名称。
1
2
3
4
5
6
/*ODS GRAPHICS语句设置图片的宽、高、边界、名字、格式,并要求绘制累积事件*/
ods graphics on / width=20cm height=18cm noborder imagename="failureplot" outputfmt=jpg;
proc lifetest data=sashelp.bmt plots=(s(f));
time t*status(0);
strata group;
run;
  • ODS Graphics设计器:通过图形化交互式界面创建、设计个性化的ODS Graphics,并自动生成GTL
    • 运行SAS自带的宏程序%sddesign来启动
    • 菜单->工具->SAS ODS Graphics设计器启动
  • ODS Graphics编辑器:通过图形化的交互式界面修改ODS Graphics的元素
1
2
3
4
5
6
7
8
/*在ODS Destination中用sge-on来打开,再生成ODS Graphics时,就会生成可编辑的SGE文件*/
ods html sge=on;
ods graphics on / width=20cm height=18cm noborder imagename="failureplot" outputfmt=jpg;
proc lifetest data=sashelp.bmt plots=(s(f));
time t*status(0);
strata group;
run;
ods html sge=off;
  • ODS Graphics 过程:通过简单、简洁的语法创建各式各样的统计图形,包括5个过程:
    • SGPLOT:创建多种多样的单个图(单格图)
    • SGPANEL:创建面板图(多格图)
    • SGSCATTER:创建矩阵散点图
    • SGDESIGN:基于SAS ODS Graphics 设计器文件创建图形
    • SGRENDER:基于图形模版语言(GTL)和SGE文件创建图形
1
2
3
4
5
6
7
8
proc sgplot data=sashelp.class;
scatter x=height y=weight;
reg x=height y=weight / cli clm;
run;
proc sgplot data=sashelp.class;
vbar sex / respose=weight;
run;
  • SAS GTL:图形模版语言,一种创建复杂的、个性化图形的绘图语言。具体使用时先通过TEMPLATE过程定义,再通过SGRENDER加载渲染。

    1. 定义,在PROC TEMPLATE过程中用DEFINE STARTGRAPH语句块定义绘图模版。

    proc template;

    ​ define statgraph template-name;

    ​ begin graph / <options>;

    ​ <gtl statements to define the graph>

    ​ endgraph;

    ​ end;

    run;

    1. 渲染,用PROC SGRENDER关联绘图数据与绘图模版,渲染生成图形。

    proc serenader data=data-set-name

    ​ template=template-name;

    run;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
proc template;
define statgraph scatterreg;
begingraph;
layout overlay;
scatterplot x=height y=weight;
regressionplot x=height y=weight / name="fitline" legendlabel="Regression line" clm="clm" cli="cli";
modelband "clm" / name="bandclm" legendlabel="95% CLM" datatransparency=0.3;
modelband "cli" / name="bandcli" legendlabel="95% CLI" display=(outline);
discreatelegend "fitline" "bandclm" "bandcli";
endlayout;
endgraph;
end;
run;
proc sgrender data=sashelp.class template=scatterreg;
run;

设计原则

  • Less is more
  • 点:让每一个点清晰可见。
  • 线:不同组的线条应该用不同颜色或不同样式区分,可依据需要添加趋势线和参考线。
  • 条:一般不给条加边框,不建议条之间重叠,条与条之间间隔比例为1:1.5~1:0.5为宜;建议颜色填充而非样式,可用颜色强度代表重要程度;如果希望显示排名顺序或分类标签太长、分类太多,建议用横向条图。
  • 刻度线:刻度尺过于离散,建议用Log转换,一般情况下,纵坐标刻度要从零开始
  • 图例:确实需要说明时才增加图例;为不使图例喧宾夺主,一般不加边框;图例一般置于图右侧,若图较宽、图例文字较长时,图例横向置于图内的上/下方。
  • 其他:不建议用饼图、不建议用3D图

条图系列

单式条图

要分析的变量就一个分类变量时,此时适用单式条图或百分比条图。

  • HBAR:横向条图
  • VBAR:纵向条图
  • CATEGORYORDER=:排序方式
1
2
3
4
5
6
7
proc sgplot data=sashelp.cars;
hbar DriveTrain / categoryorder=respdesc; /*横向 响应值降序*/
run;
proc sgplot data=sashelp.cars;
vbar DriveTrain / categoryorder=respssc; /*纵向 响应值升序*/
run;

横向条图

频数图

使PROC FREQ里TABLE语句的选项PLOTS=FREQPLOTS,此选项会自动调用ODS Graphics System绘制频数图。

1
2
3
proc freq data=sashelp.cars;
table DriveTrain / plots=freqplots;
run;

频数图

带误差限的单式条图

  • RESPONSE:指定连续变量
  • STAT=:指定统计指标
  • LIMITSTAT=:stddev, stderr, clm 指定限制线统计量
  • LIMITS=:upper, lower, both 指定限制线展示形式
1
2
3
proc sgplot data=sashelp.cars;
vbar type /response=msrp stat=mean limitstat=stddev limits=upper;
run;

带误差限的单式条图条图

单式百分比条图

单式百分比条图在绘制时需要先增加辅助分组变量,而后通过PROC SGPLOT的HBAR或VBAR实现。

  • GROUP=:指定分组变量
  • GROUPDISPLAY=:指定为堆叠方式显示
  • STAT=PERCENT:指定统计指标为百分比
1
2
3
4
5
6
7
8
data cars;
set sashelp.cars;
Drive_Train="Drive Type"; /**/
run;
proc sgplot data=cars noborder;
hbar Drive_Train / group=DriveTrain groupdisplay=stack stat=percent categoryorder=respdesc;
run;

单式百分比条图

簇拥式复式条图

单式百分比条图就是复式条图的一种特例。

  • GROUP=:指定分组变量
  • GROUPDISPLAY=:控制分组显示方式,簇拥式(cluster),堆叠式(stack)
1
2
3
proc sgplot data=sashelp.cars;
vbar origin / group=DriveTrain groupdisplay=cluster;
run;

簇拥式复式条图

簇拥式复式误差限条图

  • RESPONSE:指定连续变量
  • STAT=:指定统计指标
  • LIMITSTAT=:stddev, stderr, clm 指定限制线统计量
  • LIMITS=:upper, lower, both 指定限制线展示形式
  • GROUP=:指定分组变量
1
2
3
proc sgplot data=sashelp.cars;
vbar origin / response=msrp stat=mean group=type groupdisplay=cluster limitstat=stddev limits=lower;
run;

簇拥式复式误差限条图

复式百分比条图

  • PCTLEVEL=GROUP:控制百分比为分组的百分比
1
2
3
4
5
6
7
proc sgplot data=sashelp.cars pctlevel=group;
vbar origin / group=DriveTrain groupdisplay=cluster stat=percent; /*簇拥式*/
run;
proc sgplot data=sashelp.cars pctlevel=group;
vbar origin / group=DriveTrain groupdisplay=stack stat=percent; /*堆叠式*/
run;

簇拥式复式误差限条图

马赛克图

使PROC FREQ里TABLE语句的选项PLOTS=MAOSAICPLOT,此选项会自动调用ODS Graphics System绘马赛克图。

1
2
3
proc freq data=sashelp.cars;
table origin*DriveTrain / plots=mosaicplot;
run;

马赛克图

镜面式复式条图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
data pop; /*创建测试数据集*/
length AgeGroup $12;
do AgeGroup='Pre Teen', 'Teen', 'Young Adult', 'Adult', 'Senior';
Male=round(500*(1+ranuni(2)));
Female=round(400*(1+ranuni(2)));
output;
end;
run;
data butterfly; /*变换镜面数据*/
set pop;
Male=-male;
zero=0;
run;
proc format; /**/
picture positive low-<0='0000' 0<-high='0000';
/*0-high包含0 0<-high不包含0*/
run;
proc sgplot data=ButterFly; /*横向镜面*/
format male female positive.;
hbarparm category=agegroup response=male;
hbarparm category=agegroup response=female;
xaxis display=(noline nolabel) values=(-1000 to 1000 by 200);
yaxis display=(noline nolabel);
keylegend / position=right across=1 noopaque;
run;
proc sgplot data=ButterFly; /*纵向镜面*/
format male female positive.;
vbarparm category=agegroup response=male;
vbarparm category=agegroup response=female;
xaxis display=(noline nolabel);
yaxis display=(noline nolabel) values=(-1000 to 1000 by 200);
keylegend / position=right across=1 noopaque;
run;

横向镜面复式条图

面板条图

通过PROC SGPANEL实现面板条图,用PANELBY语句指定面板分量。

1
2
3
4
5
6
7
8
9
proc sgpanel data=sashelp.cars pctlevel=group; /**/
panelby type;
vbar origin / group=DriveTrain groupdisplay=cluster stat=percent;
run;
proc sgpanel data=sashelp.cars pctlevel=group; /**/
panelby type;
vbar origin / group=DriveTrain groupdisplay=stack stat=percent categoryorder=respdesc;
run;

簇拥式面板条图

直方图系列

简单直方图

  • NBINS:直方的数量
  • BINWIDTH:直方的宽度
1
2
3
4
5
6
7
proc sgplot data=sashelp.cars; /*简单直方图(sgplot)*/
histogram msrp / nbins =20;
run;
proc univariate data=sashelp.cars; /*简单直方图(univariate)*/
histogram msrp;
run;

简单直方图

重叠直方图

  • 可以用GROUP设置分组变量,也可以用多个HISTOGRAM语句叠加
  • 使用TRANSPARENCY设置透明度
1
2
3
4
5
6
7
8
proc sgplot data=sashelp.cars; /*通过group设置分组变量*/
histogram msrp / nbins=20 group=type;
run;
proc sgplot data=sashelp.cars; /*多个histogram叠加*/
histogram mpg_city / binstart=0 binwidth=2 transparency=0.5;
histogram mpg_highway / binstart=0 binwidth=2 transparency=0.5;
run;

重叠直方图

镜面直方图

无法通过 SGPLOT直接实现,需要借助GTL语言。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*定义模版*/
proc template;
define statgraph MirrorHistogramVert;
dynamic _binwidth;
begingraph;
entrytitle "Mileage distribution";
/*定义布局*/
layout lattice / columndatarange=union rowgutter=0;
/*定义横轴*/
columnases;
columnaxis / display=(tickvalues) griddisplay=on linearopts=(tickvaluesequence=(start=0 end=60 increment=10) tickvaluepriority=true);
endcolumnases;
/*上部分直方图*/
layout overlay / walldisplay=none xaxisopts=(griddisplay=on) yaxisopts=(griddisplay=on display=(tickvalues label) linearopts=(tickvaluesequence=(start=5 end=25 increment=5) tickvaluepriority=true));
histogram mpg_city/binstart=0 binwidth=_binwidth binaxis=false fillattrs=graphdata1 datatransparency=0.3;
entry halign=right "City Mileage" / valign=top;
endlayout;
/*下部分直方图*/
layout overlay / walldisplay=none xaxisopts=(griddisplay=on) yaxisopts=(reverse=true griddisplay=on display=(tickvalues label) linearopts=(tickvaluesequence=(start=5 end=25 increment=5) tickvaluepriority=true));
histogram mpg_highway/binstart=0 binwidth=_binwidth binaxis=false fillattrs=graphdata2 datatransparency=0.3;
entry halign=right "City Mileage" / valign=top;
endlayout;
endlayout;
endgraph;
end;
run;
/*渲染模版*/
ods graphics / NOBORDER reset width=5in height=3in imagename="MirrorHistogramVert";
proc sgrender data=sashelp.cars template=MirrorHistogramVert;
dynamic _binwidth=2;
run;

镜面直方图

面板直方图

通过PROC SGPANEL和HISTOGRAM语句来实现

1
2
3
4
5
proc sgpanel data=sashelp.cars;
panelby origin / layout=columnlattice;
histogram mpg_city / binstart=0 binwidth=2 transparency=0.5;
histogram mpg_highway / binstart=0 binwidth=2 transparency=0.5;
run;

面板直方图

箱型图系列

箱线图提供了更为明确的统计量信息,如均数,P25,P50以及P75。箱线图可以通过PROC SGPLOT的VBOX或HBOX实现。

简单箱型图

1
2
3
4
5
6
7
proc sgplot data=sashelp.cars;
vbox msrp; /*纵向*/
run;
proc sgplot data=sashelp.cars;
hbox msrp; /*横向*/
run;

简单箱型图

分组箱型图

分组箱形图的绘制只需在VBOX或HBOX语句中增加用GROUP分组变量即可。

1
2
3
proc sgplot data=sashelp.cars;
vbox msrp / group=type;
run;

分组箱型图

面板箱型图

面板箱型图可通过PROC SGPANEL过程实现。

1
2
3
4
proc sgpanel data=sashelp.cars;
panelby origin / layout=columnlattice;
vbox msrp / group=type;
run;

面板箱型图

散点图系列

X-Y散点图

X-Y散点图可通过PROC SGPLOT的SCATTER语句实现。

1
2
3
proc sgplot data=sashelp.cars;
scatter x=horsepower y=mpg_highway;
run;

X-Y散点图

X-Y散点回归图

  • 使用REG语句增加回归线
1
2
3
4
proc sgplot data=sashelp.cars;
scatter x=horsepower y=mpg_highway;
reg x=horsepower y=mpg_highway;
run;

X-Y散点回归图

分组散点图

  • 使用GROUP选项增绘制分组散点图
1
2
3
proc sgplot data=sashelp.cars;
scatter x=horsepower y=mpg_highway / group=type;
run;

分组散点图

面板散点图

在PROC SGPANEL中用PANELBY语句指定分面变量,而后用SCATTER语句绘制散点图。

1
2
3
4
proc sgpanel data=sashelp.cars;
panelby origin / layout=columnlattice;
scatter x=horsepower y=mpg_highway / group=type;
run;

面板散点图

泡泡图

增加一个变量控制散点图中点的大小,通过PROC SGPLOT中的BUBBLE实现。

1
2
3
proc sgplot data=sashelp.cars;
bubble x=horsepower y=mpg_highway size=cylinders;
run;

泡泡图

矩阵散点图

探查多个变量之间两两的关系。通过PROC SGSCATTER实现。

1
2
3
proc sgscatter data=sashelp.cars;
matrix mpg_highway horsepower enginesize / diagonal=(histogram noraml);
run;

矩阵散点图

折线图系列

简单折线图

若X与Y一一对应,可以用SERIES语句绘制。

1
2
3
proc sgplot data=sashelp.stocks (where=(date >= "01jan2002"d and stock="IBM"));
series x=date y=close;
run;

简单折线图(X与Y一一对应)

若X与Y不是一一对应,可以用VLINE或HLINE语句绘制。

1
2
3
proc sgplot data=sashelp.cars;
vline cylinders / response=msrp stat=mean markers;
run;

简单折线图(X与Y不是一一对应)

误差折线图

使用LIMITS和LIMITSTAT。

1
2
3
proc sgplot data=sashelp.cars;
vline cylinders / response=msrp stat=mean limits=both limitstat=stddev markers;
run;

误差折线图

分组误差折线图

用GROUP选项指定分组变量。

1
2
3
proc sgplot data=sashelp.cars;
vline cylinders / response=msrp stat=mean group=type limits=both limitstat=stddev markers;
run;

分组误差折线图

面板误差折线图

PROC SGPANEL过程中使用PANELBY语句。

1
2
3
4
proc sgpanel data=sashelp.cars;
panelby origin / layout=columnlattice;
vline cylinders / response=msrp stat=mean group=type limit=both limitstat=stddev markers;
run;

面板误差折线图

面积图系列

面积图

通过PROC SGPLOT的BAND语句实现。

1
2
3
4
5
6
7
8
9
10
/*重叠面积图*/
proc sgplot data=sashelp.stocks(where=(date>="01jan2002"d and stock="IBM"));
band x=date lower=0 upper=high / legendlabel="High";
band x=date lower=0 upper=low / legendlabel="Low";
run;
/*非重叠面积图*/
proc sgplot data=sashelp.stocks(where=(date>="01jan2002"d and stock="IBM"));
band x=date lower=0 upper=high / legendlabel="High";
run;

面积图

带状图

通过PROC SGPLOT的BAND语句实现。

1
2
3
proc sgplot data=sashelp.stocks(where=(date>="01jan2002"d and stock="IBM"));
band x=date lower=low upper=high / legendlabel="High";
run;

带状图

拟合图系列

密度曲线

可以用PROC UNIVARIATE过程中的HISTOGRAM语句,也可以用PROCSGPLOT的DENSITY语句。

1
2
3
4
5
6
7
8
proc univariate data=sashelp.cars; /*统计过程*/
histogram msrp / normal;
run;
proc sgplot data=sashelp.cars; /*绘图过程*/
histogram msrp / nbins=20;
density msrp;
run;

密度曲线

回归线

可以用PROC REG过程中的PLOTS选项,也可以用PROC SGPLOT的REG语句。

1
2
3
4
5
6
7
8
proc reg data=sashelp.cars plots(only)=fitplot; /*统计过程*/
model mpg_highway=horsepower;
run;
proc sgplot data=sashelp.cars; /*绘图过程*/
scatter x=horsepower y=mpg_highway;
reg x=horsepower y=mpg_highway / cli clm;
run;

回归线

椭圆曲线

通过PROC SGPLOT的ELLIPSE语句实现。

1
2
3
4
proc sgplot data=sashelp.cars;
scatter x=horsepower y=mpg_highway;
ellipse x=horsepower y=mpg_highway;
run;

椭圆曲线

ROC曲线

通过PROC LOGISTIC回归的PLOTS选项实现。

1
2
3
4
proc logistic data=sashelp.heart plots=roc;
class sex Chol_Status BP_Status Weight_Status Smoking_Status;
model Status(event="Dead")=AgeAtStart sex Chol_Status BP_Status Weight_Status Smoking_Status;
run;

ROC曲线

Kaplan-Meier曲线

通过PROC LIFETEST的PLOTS选项实现。

1
2
3
4
5
/*生存曲线*/
proc lifetest data=sashelp.bmt plots=s;
time t*status(0);
strata group;
run;

生存曲线

1
2
3
4
5
/*累积事件*/
proc lifetest data=sashelp.bmt plots=s(failure);
time t*status(0);
strata group;
run;

累积事件

LOESS曲线

局部加权回归散点发(Locally Weighted Scattered Plot Smoothing, LOESS)

  • PROC LOESS过程的PLOTS语句,AICC选项指定平滑程度
  • PROC SGPLOT过程的LOESS语句,SMOOTH选项指定平滑程度
1
2
3
4
5
6
7
proc loess data=sashelp.cars plots(only)=(FItPlot);
model mpg_highway=horsepower / select=AICC alpha=0.05 all;
run;
proc sgplot data=sashelp.cars;
loess x=horsepower y=mpg_highway;
run;

LOESS曲线

Spline曲线

SAS中最容易实现的样条函数是Penalized B-Spline Curve,可通过PROC SGPLOT里的PBSPLINE语句绘制。

1
2
3
proc sgplot data=sashelp.cars;
pbspline x=horsepower y=mpg_highway;
run;

LOESS曲线

森林图系列

通过PROC SGPLOT的SCATTER语句及其XERRORUPPER和XERRORLOWER选项绘制,或通过highlow语句绘制。

简单森林图

  • 用HIGHLOW语句绘制效应值机器95%CI
  • 文字部分借助9.4的新语句YAXISTABLE直接插入文字变量
1
2
3
4
5
6
7
8
9
10
11
12
13
proc sgplot data=fr noautolegend nocycleattrs nowall noborder;
/*文字*/
yaxistable Study CABG PCI_DES RR / position=left labelattrs=(size=7);
/*图*/
scatter y=study x=rr_m / markerattrs=graphadata2(symbol=squarefilled);
scatter y=study x=rr_2 / markerattrs=graphadata2(symbol=diamondfilled size=10);
highlow y=study low=rr_1 high=rr_u / type=line;
/*坐标轴*/
xaxis values=(0 to 3 by 1) display=(nolabel) valueattrs=(size=7);
yaxis display=none fitpolicy=none reverse colorbands=even valueattrs=(size=7) colorbandattrs=Graphdatadefault(transparency=0.8);
/*参考线*/
refline 1 /axis=x noclip;
run;

简单森林图

亚组分析森林图

SAS 9.40M3的STYLEATTRS语句新增了AXISEXTENT选项,YAXISTABLE语句增加了INDENTWEIGHT和PAD选项,可以单凭SGPLOT完美实现亚组分析森林图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
proc sgplot data=forest_subgroup_2 nowall noborder nocycleattrs dattrmap=attrmap noautolegend;
styleattrs axisextent=data;
/*左边的文字*/
yaxistable subgroup / location=inside position=left textgroup=id labelattrs=(size=7) textgroupid=text indentweight=indentWt;
yaxistable countpct / location=inside position=left labelattrs=(size=7) valueattrs=(size=7);
yaxistable PCIGroup group pvalue / location=inside position=right pad=(right=15px) labelattrs=(size=7) valueattrs=(size=7);
/*绘制95%CIBAR*/
highlow y=obsid low=low high=high;
/*绘制Bar的中点*/
scatter y=obsid x=mean / markerattrs=(symbol=squarefilled);
/*二次绘制Bar中点,关联x2axis*/
scatter y=obsid x=mean / markerattrs=(size=0) x2axis;
/*底部文字*/
text x=xl y=obsid text=text / position=bottom contributeoffsets=none strip;
format text $txt.;
/*坐标轴*/
yaxis reverse display=none colorbands=odd colorbandsattrs=(transparency=1) offsetmin=0.0;
xaxis display=(nolabel) values=(0.0 0.5 1.0 1.5 2.0 2.5);
x2axis label='Hazard Ratio' display=(noline noticks novalues) labelattrs=(size=8);
/*参考线*/
refline 1 / axis=x;
refline ref / lineattrs=(thickness=13 color=cxf0f0f7);
run;

亚组分析森林图

地图系列

纯地图

  • MAP:指定地图数据集
  • DATA:指定反应数据集,即使不在地图上绘制反应变量,仍需指定反应数据集(反应数据集可以和地图数据集是一个数据集)
  • 添加各州名称标注:用USattr这个属性数据集,并利用SAS自带的宏给地图增加标签说明文字,生成标注数据集,然后绘制地图时用ANNO选项指定标注数据集。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
%annomac
%maplabel(mapsgfk.us, mapsgfk.us_states_attr(keep-id idname), anno_label,idname, id)
proc gmap map=maps.us data=maps.us;
id state;
choro state / nolegend anno=anno_label;
run;
quit;
proc gmap map=maps.us data=maps.us;
id state;
choro state / nolegend;
run;
quit;
proc gmap map=mapsgfk.us data=mapsgfk.us;
id id;
choro id / nolegend;
run;
quit;

纯地图

统计地图

BLOCK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
data sample;
input st $ pop2010 @@;
state=stfips(st);
datalines;
AL 4779 Ak 710 AZ 6392 AR 2815 CA 37253 CO 5029 CT 3574 DE 897 DC 601 FL 18801
GA 9687 HI 1360 ID 1567 IL 12830 IN 6483 IA 3046 KS 2853 KY 43339 LA 4533
ME 1328 MD 5773 MA 6547 MI 9883 MN 5303 MS 2967 MO 5988 MT 989 NE 1826 NV 2700
NH 1316 NJ 8791 NM 2059 NY 19378 NC 9535 ND 672 OH 11536 OK 3751 OR 3831
PA 12702 RI 1052 SC 4625 SD 814 TN 6346 TX 25145 UT 2763 VT 6257 VA 8001
WA 6724 WV 1852 WI 5686 WY 563 PR 3725
;
run;
proc gmap map=maps.us data=sample;
id state;
block pop2010 / level=6;
format est2015 pop2010 comma12.;
run;
quit;

统计地图

热力地图

CHORO

1
2
3
4
5
6
proc gmap map=maps.us data=sample;
id state;
choro pop2010 / level=6;
format est2015 pop2010 comma12.;
run;
quit;

热力地图

PROC SGPLOT总结

PROC SGPLOT <*option(s)>;

​ STYLEATTRS </*option(s)>;

​ PLOT STATEMENT </*option(s)>;

​ XAXIS <*option(s)>;

​ X2AXIS <*option(s)>;

​ YAXIS <*option(s)>;

​ Y2AXIS <*option(s)>;

​ KEYLEGEND <“name-1” … “name-n”> </*option(s)>;

​ GRADLEGEND <“name”> </*option(s)>;

RUN;

SGPLOT and SGPANEL plot statements and selected options

syntax selected options
SCATTER scatter x=var y=var / options; datalabel=var Displays a label for each data point
SERIES series x=var y=var / options; break Creates a break in the line for each missing value
curvelabel Labels the series curve using the Y variable label
STEP step x=var y=var / options; break Creates a break in the line for each missing value
curvelabel Labels the series curve using the Y variable label
NEEDLE needle x=var y=var / options; baseline=val specifies a numeric value on the Y axis for the baseline
VECTOR vector x=var y=var / options; xorigin=val specifies Xcoordinate for origin either numeric value or numeric variable
yorigin=val specifies Ycoordinate for origin either numeric value or numeric variable
BUBBLE bubble x=var y=var size=var / options; fill specifies fill is visible
nofill specifies fill is not visible
outline specifies outline is visible
nooutline specifies outline is not visible
BAND band x=var upper=var lower=var / options; fill specifies fill is visible
nofill specifies fill is not visible
outline specifies outline is visible
nooutline specifies outline is not visible
HIGHLOW highlow x=var high=var lo=var / options; highcap=val specifies type of cap to use at end of bar or line
lowcap=val specifies type of cap to use at end of bar or line
type=val specifie how to draw glot with a: BAR or LINE(default)

图片属性控制

  • GPATH:存储位置
  • DPI:分辨率
  • WIDTH:宽
  • HEIGHT:高
  • OUTPUTFMT:格式
1
2
ods html style=ggStyle gpath='d:\StatsGraph' dpi=600;
ods graphics / width=14cm height=10cm outputfmt=jpg;

输出终端LISTING既支持EPS矢量图,也支持TIF位图。

1
2
3
4
5
6
7
8
9
ods listing gpath="D:\myGraph" dpi=300;
ods graphics on / imagename="eps" outputfmt=EPS; /*矢量图*/
绘图语句;
ods graphics on / imagename="tif" outputfmt=TIF; /*位图*/
绘图语句;
ods listing close;

PRINTER终端的优势是可以在一个语句里同时设置格式和分辨率,但劣势是绘制的图片仅仅是其输出的一部分区域。

1
2
3
4
5
6
7
ods printer printer=Postscript FILE="D:\eps.eps" dpi=300; /*矢量图*/
绘图语句
ods printer close;
ods printer printer=tiff FILE="D:\tif.tif" dpi=300; /*位图*/
绘图语句
ods printer close;

《SAS编程演义》笔记(5-7章)

Posted on 2017-09-13 | In SAS

亦应帷幄运鸿筹:数据库集

修改数据集

MODIFY master-data-set <(data-set-options)> transaction-data-set <(data-set-options)> <CUROBS=variable> < NOBS=variable> <END=variable> <UPDATEMODE=MISSINGCHECK|NOMISSINGCHECK>;

BY by-variable;

  • master-data-set:主数据集(Master Dataset),存放原始数据。
  • transaction-data-set:事物数据集(Transaction Dataset),存放匹配变量、需要修改的变量及其新值。
  • CUROBS=variable:将当前生成的数据集观测存储到临时变量variable中
  • NOBS=variable:将主数据集和事物数据集总观测数存储到临时变量variable中
  • END=variable:创建并命名一个临时变量variable,用1和0标记是否为最后一条记录。

MODIFY master-data-set <(data-set-options)> KEY=index </UNIQUE> <KEYRESET=variable> <NOBS=variable> <END=variable>;

  • KEY=index:指定索引
  • KEYRESET=variable:是否从索引头部查找

MODIFY master-data-set <(data-set-options)> <NOBS=variable> POINT=variable;

  • POINT=variable:随机读取由variable指定的观测

MODIFY master-data-set <(data-set-options)> <NOBS=variable> <END=variable>

MODIFY比SET更高效。MODIFY语句直接修改原数据集,不生成新数据集。SET语句打开原数据集,重新生成一份新数据集(即使新数据集与原数据集同名)。因此使用MODIFY语句时,DATA语句后必须是原数据集,但使用SET语句时则无所谓。

1
2
3
4
5
6
7
8
9
10
11
data class;
set sashelp.class;
weight = weight*0.4536; /*lbs->kg*/
height = height*0.0254; /*in->m*/
run;
data sashelp.class;
modify sashelp.class;
weight = weight*0.4536; /*lbs->kg*/
height = height*0.0254; /*in->m*/
run;

MODIFY比MERGE更高效。MODIFY语句进行匹配修改观测时,因其采用动态WHERE语句,不像MERGE需要事先排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
data raw;/*主数据集*/
name="吴源燚";gender="";age=2;Location="SH";output;
name="WUYY";gender="M";age=.;Location="SH";output;
run;
data new;/*事物数据集*/
name="吴源燚";gender="M";
name="WUYY";age=25;output;
name="WUYY";age=30;output;
run;
data raw;
modify raw new;
by name;
replace; /*默认可省略*/
run;

MODIFY语句是对原数据集里观测进行修改,但是不能改变数据集结构,即不能新增变量也不能新增观察。

1
2
3
4
5
6
7
8
9
10
11
data sashelp.class class_female;
modify sashelp.class;
if sex ="F" then do;
output class_female;
remove sashelp.class;
end;
else do;
height=height+5;
replace sashelp.class;
end;
run;

更新数据集

UPDATE master-data-set <(data-set-options)> transaction-data-set <(data-set-options)> <END=variable> <UPDATEMODE=MISSINGCHECK|NOMISSINGCHECK>;

BY by-variable;

  • master-data-set:主数据集,存放原始数据。
  • transaction-data-set:事物数据集,存放匹配变量、需要修改的变量及其新值。
  • END=variable:创建并命名一个临时变量variable,用1和0标记是否为最后一条记录。
  • UPDATEMODE:是否用事物数据集里的缺失值更新主数据集
    • 是:NOMISSINGCHECK
    • 否:MISSINGCHECK
  • by-variable:指定匹配变量,主数据集和事物数据集按变量的值 匹配

主数据集和事物数据集需先按BY变量排序;UPDTATE只有一种用法,其后必须跟BY语句;主数据集中,BY变量的值应该唯一,否则只会更新相同值的首条记录,事物数据集中BY变量值可以不唯一,更新的数据集最终会以最后一条为准。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
data raw;/*主数据集*/
name="吴源燚";gender="";age=2;Location="SH";output;
name="WUYY";gender="M";age=.;Location="SH";output;
run;
data new;/*事物数据集*/
name="吴源燚";gender="M";
name="WUYY";age=25;output;
run;
proc sort data=raw; /*排序*/
by name;
run;
proc sort data=new;
by name;
run;
data want; /*用事物数据集更新主数据集*/
update raw new;
by name;
run;

行列转置

PROC TRANSPOSE <DATA=input-data-set> <DELIMITER=delimiter> <LABEL=label> <LET> <NAME=name> <OUT=output-data-set> <PREFIX=prefix> <SUFFIX=suffix>;

BY <DESCENDING> variable-1 <<DESCENDING> variable-2> <NOTSTORED>;

COPY variable(s);

ID variable;

IDLABEL variable;

VAR variable(s);

RUN;

  • DATA=input-data-set:待转置数据集名称
  • DELIMITER=delimiter:ID语句有多个变量时,变量值之间所加的连字符
  • LABEL=label:转置变量的标签存储在新数据集中的变量名,默认_LABEL_
  • LET:当ID变量的值有重复时使用,此时只有每组ID的最后一条观测被转置
  • NAME=name:转置变量在新数据集中的名字,默认为_NAME_
  • OUT=output-data-set:转置后数据集名称
  • PREFIX=prefix:给转置变量在新数据集中的变量名加前缀
  • SUFFIX=suffix:给转置变量在新数据集中的变量名加后缀
  • BY:制定分组转置的变量,如果没有加NOTSTORED选项,原数据集应该先用PRCO SORT语句按BY语句指定的变量排序
  • COPY:拷贝变量,此变量不转置,直接拷贝到新数据集中
  • ID:标识变量,用此变量的值标识转置后变量的名称,多个标识变量时,需要DELIMITER指定连字符
  • IDLABEL:给转置后的变量添加标签
  • VAR:待转置的变量,SAS将对此变量进行行列互换操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
data wide; /*创建宽表*/
input SID $ Programming Stats English;
datalines;
S01 98 100 80
S02 84 98 94
S03 89 92 88
;
run;
proc transpose data=wide out=long(rename=(_name_=Coursename col1=Score));
var Programming Stats English;
by SID;
run;
data long(keep= SID Coursename Score);
set wide;
array scores{*} Programming Stats English;
do i=1 to dim(scores);
Coursename=vname(scores{i});
Score=Scores{i}
end;
run;
proc transpose data=long out=Rewide(drop=_name_);
var Score;
by SID;
id Coursename;
run;
data Rewide(keep=SID Programming Stats English);
format SID Programming Stats English;
array Course{3} Programming Stats English;
do i=1 to 3;
set long;
Course{i}=Score;
end;
run;

横向拼接(并接)

一对一读入(One-to-one Reading)

  • 用多SET语句并接多个数据集,当数据集里的观测数不等时,SAS读完观测数最少的那个数据集后即停止执行。
  • 当多个数据集里的变量有重复时,后面的值会覆盖前面的值。
1
2
3
4
5
6
7
8
9
10
data class1(keep=name sex) class2(keep=age height weighr);
set sashelp.class;
output class1;
output class2;
run;
data class;
set class1;
set class2;
run;

一对一并接(One-to-one Merging)

  • 数据不对等时,不会停止执行。
1
2
3
data class;
merge class1; class2;
run;

匹配并接(Matching Merging)

  • 在使用MERGE语句前需用PROC SORT过程给匹配变量排序,在其之后需紧接BY语句指定匹配变量。
  • 可同时MERGE多个数据集,对于相同的变量,后一个数据集里的值会覆盖前一个数据的值。
  • 并接两个数据集时,BY变量可能不唯一。一个数据集重复的BY值有m个,另一数据集重复的BY值有n个,则MERGE后,这些重复的BY值将产生m*n条结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
data class1(keep=name sex) class2(keep=name age height weight);
set sashelp.class;
out class1;
if _n_ in (1, 5, 10, 15) then output class2;
run;
data class2;
ser class2;
if name="Janet" then name="Janey";
run;
proc sort data=class2;
by name;
run;
proc sort data=class2;
by name;
run;
data class_left; /*左连接*/
merge class1(in=ds1) class2(in=ds2);
by name;
if ds1;
run;
data class_right; /*右连接*/
merge class1(in=ds1) class2(in=ds2);
by name;
if ds2;
run;
data class_inner; /*内连接*/
merge class1(in=ds1) class2(in=ds2);
by name;
if ds1 and ds2;
run;
data class_full; /*全连接*/
merge class1(in=ds1) class2(in=ds2);
by name;
if ds1 or ds2;
run;

纵向拼接(串接)

SET语句

  • SET语句后可以跟多个数据集或数据集列表
  • 最终的数据集不会自动剔除重复行
  • 为匹配的列值为空
  • 字符型变量的长度为第一次出现的数据中的定义长度,后面相同的字段如果比前面更长,则会被截断,因此建议在SET语句前先用LENGTH语句申明其长度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
data class1 class2 class3(keep=name sex) class4(keep=name age height weight);
set sashelp.class;
if _n_ < 10 then do;
output class1;
output class2;
end;
else do;
output class2;
output class4;
end;
run;
data class;
set class1 class2;
run;
data class;
set class2 class4;
run;

PROC APPEND

PROC APPEND BASE=<libref.>SAS-data-set <APPENDVER=V6> <DATA=<libref.>SAS-data-set> <ENCRYPTKEY=key-value> <FROCE> <GETSORT> <NOWARN>;

RUN;

  • BASE=<libref.>SAS-data-set:指定基础数据集,追加数据集的观测将写入此数据集中
  • APPENDVER:指定追加机制的版本,可以是V6或V7
  • DATA=<libref.>SAS-data-set:指定待追加数据集
  • ENCRYPTKEY=key-value:AES加密键值
  • FORECE:当追加数据集里的变量不在BASE数据集,或者变量类型和长度不同时,强制追加,不过此时LOG中会有警告信息,可以用NOWARN屏蔽
  • GETSORT:把BASE数据集的排序标识复制到追加数据集中
1
2
proc append base=class3 data=class4 force;
run;

制作变量字典

利用ODS OUTPUT语句抓取PROC CONTENTS背后的数据

1
2
3
4
5
6
ods output Position=codebook;
proc contents data=sashelp.cars order=varnum;
run;
proc export data=codebook outfile="d:\codeBook.csv" dbms=csv replace;
run;

数据集信息

数据集权限有读、写、修改和全局四种,分别用READ=、WRITE=、ALTER=、PW=来设置。格式为:密码1/密码2,具体有五种形式:

  • 密码1:设置密码
  • 密码1/密码2:修改密码1为密码2
  • 密码2:不管旧密码是什么,设置新密码为密码2
  • 密码1/:删除密码
  • /:删除密码
1
2
3
4
5
6
7
proc datasets lib=sashelp; /*获取描述信息*/
contents data=class;
run;
proc datasets lib=sashelp;/*修改描述信息*/
modify class(label="学生测试数据集" read=r2017);
quit;

数据集操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
proc datasets;
copy in=sashelp out=work; /*数据集集体拷贝*/
select class; /*选择数据集*/
quit;
proc datasets lib=work;
change class=student; /*数据集改名*/
quit;
proc datasets lib=work;
delete students; /*删除数据集*/
quit;
proc datasets lib=work kill memtype=data; /*删除Work库中所有数据集*/
run;
proc datasets lib=work;
save class; /*仅保留class*/
run;

变量信息

PROC DATASETS不是打开数据集,逐行操作,而是对数据集的描述信息直接操作,或者直接操作整体数据集。因此相比逐条操作的SET语句,PROC DATASETS在效率上要高很多。

PROC DATASETS配合MODIFY语句,可以修改变量的格式、标签以及重命名变量。

1
2
3
4
5
6
proc datasets;
modify sashelp.class;
format height weight 3.0;
rename sex=gender;
label name="姓名" gender="性别";
quit;

SAS字典

SAS Dictionary库是一个只读的SAS逻辑库,里面包含了与SAS会话相关的元数据(描述数据的数据),如数据集名、变量名、变量类型以及变量长度等这些描述变量的变量。

1
2
3
4
proc sql;
title "Dictionary库中所有的表";
select unique memname memlabel from dictionary.dictionaries;
quit;

SAS字典库里的表与其对应的SASHELP库下的视图

Dictionary库下的表名 SASHELP库下的视图名 主要作用
TABLES Vtable 包含了诸如逻辑库名、数据文件名、数据文件的类型、观测值数、变量数等诸多信息
COLUMNS Vcolumn 包含了变量名称、类型、长度和格式以及标签等诸多信息
MEMBERS Vmember 包含了逻辑库名称、数据文件名、数据类型、路径等诸多信息
FORMATS Vformat 包含了系统自带的格式信息
1
2
3
proc sql;
describe table dictionary.column; /*查看columns表结构*/
quit;

在指定逻辑库、数据集以及数据文件类型时,需用引号,且引号里面的字母是大学。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
proc sql; /*从字典库中获取SASHELP库下所有数据集信息*/
create tables desds as select memname, nobs, nvar from dictionary.tables
where libname="SASHELP" and memtype="DATA";
quit;
proc sql; /*从视图中获取SASHELP库下所有数据集信息*/
create tables desds as select memname, nobs, nvar from sashelp.vtable
where libname="SASHELP" and memtype="DATA";
quit;
proc sql; /*从字典库中获取数据集CARS的所有变量信息*/
create table varlist as select name, type, length, label from dictionary.columns
where libname="SASHELP" and memname="CARS";
quit;
proc sql; /*从视图中获取数据集CARS的所有变量信息*/
create table varlist as select name, type, length, label from sashelp.vcolumn
where libname="SASHELP" and memname="CARS";
quit;

间有山川亦奇秀:函数例程

函数语法

可用于DATA步赋值语句、IF语句、WHERE表达式(语句或选项)、宏语句、PROC REPORT以及PROC SQL语句中。PRCO SQL的SELECT语句里的函数作用是纵向的,而其他函数的作用则是横向的。

function-name(argument-1<…*argument-n>)

function-name(OF variable-list)

function-name(OF array-name[*])

function-name(<argument|OF variable-list| OF array-name[*]> <…, <argument|OF variable-list| OF array-name[*]>>)

  • function-name:函数名称
  • argument:参数,可以是变量名、常数、表达式、甚至还可以是其他函数
  • OF variable-list:参数列表
  • OF array-name[*]:数组名称,注意要带[*]
1
2
3
4
5
6
7
8
9
10
11
data _null_;
array ex{7} (95 93 92 99 98 85 94);
avg_function1=mean(ex1, ex2, ex3, ex4, ex5, ex6, ex7); /*单个参数*/
avg_function2=mean(of ex1 ex2 ex3 ex4 ex5 ex6 ex7); /*变量清单*/
avg_function3=mean(of ex1-ex7); /*变量清单*/
avg_function4=mean(of ex:); /*变量清单*/
avg_function5=mean(of ex[*]; /*数组名*/
put (avg_function1 avg_function2 avg_function3 avg_function4 avg_function5) (=);
put avg_function1= avg_function2= avg_function3= avg_function4= avg_function5=;
/*put avg_function1 avg_function2 avg_function3 avg_function4 avg_function5;*/
run;

例程语法

主要用于DATA步的CALL语句中,不能用于赋值语句和表达式。

CALL routine-name(argument-1<…*argument-n>)

CALL routine-name(OF variable-list)

CALL routine-name(OF array-name[*])

CALL routine-name(<argument|OF variable-list| OF array-name[*]> <…, <argument|OF variable-list| OF array-name[*]>>)

  • routine-name:函数名称
  • argument:参数,可以是变量名、常数、表达式、甚至还可以是其他函数
  • OF variable-list:参数列表
  • OF array-name[*]:数组名称,注意要带[*]
1
2
3
4
5
6
7
8
9
10
data tmp;
array str{3} $20 ("统计思维","SAS编程演义","数据整理与图标呈现");
length result1-result5 $50;
call catx("-", result1, str1, str2, atr3);
call catx("-", result2, of str1 str2 atr3);
call catx("-", result3, of str1-atr3);
call catx("-", result4, of str:);
call catx("-", result5, of str[*]);
put (result1 result2 result3 result4 result5) (=);
run;

自定义函数

借助PROC FCMP的FUNCTION语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
proc fcmp outlib=sasuser.funcs.trial;
function study_day(intervention_date, event_date); /*定义函数study_day*/
n=event_date - intervention_date;
if n >= 0 then
n = n + 1;
return(n);
endsub;
run;
options cmplib=sasuser.funcs;
data _null_;
start='15Feb2010'd;
today='27Mar2010'd;
sd=study_day(start, today);
put sd=;
run;

高频函数和例程

功能类别 函数名及其功能
数组处理 DIM:返回数组元素个数
HBOULD:返回数组上界
LBOULD:返回数组下界
字符处理 STRIP:掐头去尾移除空格
SUBSTR:提取、置换字符
TRANSLATE、TRANSTRN、TRANWRD:替换、移除字符
UPCASE、LOWCASE、PROPCASE:大小写转换
SCAN:扫描整个字符串,返回某部分字符串
FIND、FINDC、FINDW:查找字符,返回其位置
INDEX、INDEXC、INDEXW:查找字符,返回其位置
CATS、CATT、CATX及其CALL例程:字符串拼接
日期时间 DATE、TODAY:获取当前日期
YEAR、MONTH、DAY:分别截取年、月、日
MDY:月、日、年组合成完整日期
HOUR、MINUTE、SECOND:分别截取时、分、秒
HMS:时、分、秒组合成完整时间
INTCK:计算日期、时间、日期时间间的间隔
INTNX:给定间隔的下一个日期、时间、日期时间
统计描述 N、NMISS:分别统计非缺失、缺失的个数
SUM:求和
MEAN:均数
STD、STDERR:标准差、标准误
CV:变异系数
IQR:分位数间隔
MISSING:判断是否缺失
宏函数 CALL SYMPUT、CALL SYMPUTX:DATA步赋值宏变量
SYMEXIT:判断宏变量是否存在
SYMGET:DATA步运行阶段获取宏变量值
截断函数 TRAN:强行截断
ROUND:四舍五入
INT、CELL、FLOOR:直接取整、向上取整、向下取整
变量信息 VNAME:获取变量名
VTYPE:获取变量类型
VLABEL:获取变量标签
特殊函数 INPUT、PUT:数据类型转换
LAG、DIF:不同观测号间的值与差值

翩跹翠袖拂云裳:巧用格式

格式名

<$>format-name<w>.<d>

$:标明是否为字符格式,有$的为字符格式,无则为数字格式

format-name:格式名称,可以是SAS系统自带也可以是用户在PROC FORMAT的VALUE语句中自定义的

w:格式的宽度

d:小数的位数

.:w和d均可以没有,但其之间的点必须保留

1
2
3
4
5
6
7
/*获取系统内置格式清单*/
proc sql;
create table SysFormats as select distinct fmtname from dictionary.formats;
quit;
proc print data= SysFormats;
run;

常用输入格式

类别 格式名 作用简介
字符 $CHARw. 读入带空格的字符
$w. 标准字符格式
日期时间 ANYDTDTEw. “万能”读入日期格式
ANYDTDTMw. “万能”读入日期时间格式
ANYDTTMEw. “万能”读入时间格式
DATEw. 读入格式为ddmmyy或ddmmyyyy的日期
DATETIMEw. 读入格式为ddmmyy hh:mm:ss或ddmmyyyy hh:mm:ss的日期时间
DDMMYYw. 读入格式为ddmmyy<yy>或者dd-mm-yy<yy>格式的日期,连字符可以是- . /
HHMMSSw. 读入格式为hh:mm:ss或hhmmss的时间
MMDDYYw. 读入格式为mmddyy或mmddyyyy的日期
数字 COMMAw.d 读入数字时移除数字间的逗号
w.d 读入标准数字格式
PERCENTw.d 读入百分比数字

常用输出格式

类别 格式名 作用简介
字符 $w. 标准字符格式,w表示变量的宽度
$IPCASEw. 把字符转成大写,相当于UPCASE函数
日期时间 DATETIMEw.d 显示日期时间格式为ddmmmyy:hh:mm:ss.ss
DATEw. 显示日期格式为ddmmmyy,ddmmmyyyy,或dd-mmm-yy
YYMMDDw. 显示日期格式为yymmdd或<yy>yy-mm-dd
HHMMw.d 显示时间格式为hh:mm
数字 BESTw. SAS自动选择最合适的数字格式
COMMAw.d 带千分位的数字格式
DOLLARw.d 带美元符号的格式
PERCENTw.d 显示百分比形式
PVALUEw.d 统计P值显示格式
w.d 标准的数字格式
Zw.d 前面位数不够补0填充

自定义格式

PROC FORMAT <option(s)>;

EXCLUDE entry(s);

INVALUE <$>name<(informat-option(s))><value-range-set(s)>;

PICTURE name<(format-option(s))> <value-range-set-1<(picture-1-option(s))> <value-range-set-2<(*picture-2-option(s))>> …>;

SELECT entry(s);

VALUE <$>name<(format-option(s))> <value-range-set(s)>

RUN;

  • option(s):PRCO FORMAT的一些选项,如:
    • library=:指定格式存放位置
    • ctnlin=:指定格式定义输入数据集
    • ctnlout=:指定格式定义到出数据集
  • EXCLUDE:剔除某些条目
  • INVALUE:定义输入格式
    • name:输入格式名,前面有$表示为字符格式名
    • informat-option(s):输入格式选项
    • value-range-set(s):数据映射
  • PICTURE:创建打印数字的模版
  • VALUE:定义输出格式
    • name:输出格式名,前面有$表示为字符格式名
    • informat-option(s):输出格式选项
    • value-range-set(s):数据映射,其形式可以是:value-or-range-1 <, value-or-range-2, …>=formatted-value|[existing-format]

直接用输入数据来定义格式时,输入数据集里必须包含五个重要字段名:FMTNAME、START、END、LABEL以及TYPE。

1
2
3
4
5
6
proc format cntlout=fmt; /*自定义格式,导出格式定义数据*/
value $sexf F="男性" M="女性";
run;
proc format library=work cntlin=fmt(keep=fmtname start end label type); /*用数据集定义格式*/
run;
  • 格式命名:格式命名长度不得超过32个字符(包括$),且不得以数字结尾
  • 数据映射中,数据范围写法:
    • 单独的值映射:如「F=”男性” M=”女性”」,「1=”低” 2=”中” 3=”高”」
    • 值范围的映射:如「18.5-24.9=”正常”」,「’A’-‘D’=”Class1”」
    • 单用连字符“-”时,是闭区间,包括两边边界值。如果希望不包括边界,可在其前加“<”,如:「18.5-<25=”正常”」
    • 可用关键词LOW,HEIGH,OTHER:如「low-<65=”<65岁” 65-high=”>=65岁”」
    • 可以嵌套格式名,但是需要将嵌套的格式名置于中括号内或小括号里的双竖线中,如:「.=”缺失” other=[yymmdd10.];」
  • 定义好的格式,如果在DATA步用FORMAT关联变量,则为永久性的;如果只在过程步用FORMAT关联变量,则为临时性的。

格式妙用

格式的使用范围

1
2
3
4
5
6
7
8
9
10
11
12
13
data _null_; /*DATA步 PUT语句中指定*/
set sashelp.class(obs=5);
put name sex $sexf.;
run;
prco print data=sashelp.class(obs=5); /*PROC步FORMAT语句指定*/
var name sex;
format sex $sexf.;
run;
proc sql; /*Proc sql中format选项*/
select name, sex format=$sexf. from sashelp.class(obs=5);
quit;

变量重分组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data obese; /*创建测试数据集*/
length status $ 15;
set sashelp.class;
BMI = weight*0.4536/(height*0.0254)**2;
run;
proc format; /*自定义格式*/
value obefmt low-18.5="Underweight" 18.5-25="Normal"
25-30="Overweight" 30-high="Obese";
run;
proc freq data=obese; /*愿变量+格式直接统计新分类的频数*/
table bmi;
format bmi obefmt.;
run;

统计分析过程

1
2
3
4
5
6
7
8
9
10
/*在统计分析过程里,直接用自定义格式给变量重分组*/
proc format;
value obefmt low-18.5="Underweight" 18.5-high="Normal or above";
run;
proc logistic data=obese;
class sex;
model bmi(event="Underweight")=age sex;
format bmi obefmt.;
run;

统计缺失观测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
proc format; /*自定义格式*/
value $missfmt ' '="Missing" other="Not Missing"; /*引号中有多少空格都一样*/
value nmissfmt .="Missing" other="Not Missing";
run;
data class; /*创建测试数据集*/
set sashelp.class;
if rannor(123)<0.5 then call missing(sex);
if rannor(456)<0.05 then call missing(age);
run;
proc freq data=class; /*统计缺失、非缺失频数*/
table sex age/missing;
format sex $missfmt. age nmissfmt.;
run;
data cclass;
set class;
if name='Henry' then sex=' ';
run;
proc freq data=cclass; /*统计缺失、非缺失频数*/
table sex age/missing;
format sex $missfmt. age nmissfmt.;
run;

条件显示

利用自定义格式,可以依据不同的条件,按不同风格显示值。

1
2
3
4
5
6
7
8
9
10
11
proc format;
value obefmt low-18.5="red" 18.5-high="black";
run;
proc report data=obese nowd split='~' style(report)=[background=white foreground=black];
column name sex age bmi;
define name/display;
define sex/display;
define age/display;
define bmi/format=4.1 style=[foreground=obefmt.];
run;

《SAS编程演义》笔记(1-4章)

Posted on 2017-09-13 | In SAS

清歌苦调两不厌:夯实基础

查看SAS安装、许可的模块

1
2
3
4
5
6
7
8
9
proc product_status; /*查看SAS已安装模块*/
run;
proc setinit; /*查看SAS已许可模块*/
run;
/*查看完整安装报告*/
%include "D:\...\sasinstallreporter4u.sas" /*SAS程序文件地址依据存储路径修改*/
%sasinstallreporter; /*查看完整安装报告*/

如何让SAS自动加载永久逻辑库

  1. 如果想要让SAS语句建立的永久库在启动后就能看到,可以把包含LIBNAME语句的程序命名为autoexe.sas,并放入和sas.exe同级的目录中,此后每次SAS启动时会自动运行autosas.exe程序。
  2. 通过工具按钮建立永久库时,可以在建立时勾上Enable at startup,下次启动SAS时就会自动加载这个永久库。

为什么又了数据文件还要视图

视图是依据查询语句动态生成,因此视图本身几乎不占据存储空间。利用视图可以节约硬盘空间。两者在世界内容效果方面是一样的。

日期与时间的本质

  1. 日期实际存储的是距离1960年1月1日的天数
  2. 时间是距离凌晨的秒数

打破SAS命名规则

修改系统选项VALIDMEMNAME和VALIDVARNAME

1
2
3
4
5
6
7
options VALIDMEMNAME=extend VALIDVARNAME=any;
data 中文名演示;
SAS中文变量名 = "YES";
SAS中文變量名 = "YES";
'2SAS中文变量名'n = "YES";
'SAS空格 #@%特殊字符变量名'n = "YES";
run;

运算符

  • 不等于 ^= ~=
  • 两者取小 ><
  • 两者取大 <>
  • 连接运算符 ||
  • 与 & and
  • 或 ! | or
  • 非 ^ ~ not

IF-ELSE配合DO-END

希望执行的不仅仅是一个动作,而是多个动作,此时可以在关键词THEN后面用夹板语句DO-END,把多个动作整合在DO-END中。

1
2
3
4
5
6
data male female;
set sashelp.class;
if sex='M' then do; gender='Male'; output male; end;
else if sex='F' then do; gender='Female'; output female; end;
else put 'Invalid sex :' sex;
run;

循环

  • DO-END
  • DO-WHILE
  • DO-UNTIL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    data random;
    do i=1 to 10;
    r=rannor(23);
    output;
    end;
    run;
    data dowhile;
    i=0;
    do while(i<5);
    i+1;
    output;
    end;
    run;
    data dountil;
    i=0;
    do until(i>=5);
    i+1;
    output;
    end;
    run;

数组结构

  • 数组中的变量必须有相同的数据类型
  • ARRAY array-name {number-of-elements} <$> <length> <array-elements> <(initial-value-list)>
  • 元素个数可以用{*}代替,让SAS自动计数;可以指定具体的数字,如{7};可以指定一定的数字范围,如{1:7}
  • 元素名可以是变量名也可以是SAS自定义变量,如_ALL_(变量类型需相同,_NUMERIC_,_CHARACTER_,_TEMPORARY_(临时变量)
  • <>中的内容并非必须有。如$和length只有在数组元素为字符型时才用到。

PDV与DATA步自循环

1
2
3
4
5
6
7
8
9
10
11
data demoPDV;
put "第" _n_ "次前运行:" _all_;
input ID $ Chiness Math English;
Sum = Chiness + Math + English;
put "第" _n_ "次后运行:" _all_;
datalines;
S001 80 99 93
S002 90 85 95
S003 83 88 81
;
run;

@与@@

  • 当DATALINES数据行里要读入的数据列数=要读入的变量数,也就是说一行就是一条观测时,无尾。
  • 当DATALINES数据行里要读入的数据列数>要读入的变量数,而且是整数倍时,也就是说一行=K*数条观测(K为>=1的整数),用@@。
  • 当一个DATA步里有多个INPUT语句时,我们需要单尾@。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    * 数据列数=变量数
    data test1;
    input id x y z;
    datalines;
    1 98 99 97
    2 93 91 92
    ;
    run;
    * 数据列数=变量数,多个input语句
    data test2;
    input id@;
    input x@;
    input y@;
    input z@;
    datalines;
    1 98 99 97
    2 93 91 92
    ;
    run;
    * 数据列数=k*变量数
    data test3;
    input id x y z @@;
    datalines;
    1 98 99 97 2 93 91 92;
    run;
    • 无尾Hold不住立即跳
    • 一尾(@)Hold住当前INPUT语句不跳,但若刚好是DATA步最后一个INPUT语句,跳。
    • 二尾(@@)打死都不跳。
    • 最后,无论多少尾,数据行末尾必定自动跳。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
data test;
input x @;
input y;
input @@;
datalines;
1 2 3
4 5 6
7
;
run;
data test;
input x;
input y @@;
input z @;
datalines;
1 2 3
4 5 6
7
;
run;

苔点狂吞纳线青:读取数据

读取方式

  • LIBNAME语句
  • SQL直通设施(SQL pss-through facility)
  • ACCESS/DBLOAD过程,已不推荐
  • IMPORT/EXPORT过程
  • INFILE+INPUT语句
  • INPUT+DATALINES语句
  • IO函数

LIBNAME访问DBMS数据文件

LIBNAME libref engine-name \<SAS/ACCESS-connection-options> \<SAS/ACCESS-LIBNAME-options>;

libname mydb2 db2 user=yuanyi password="wuyuanyi" datasrc=datadb

  • libref: 逻辑库名,其实是存放数据表和视图的DBMS数据库、架构、服务器端别名
  • engine-name: 引擎名,不同的DMBS数据文件需要指定不同的引擎名,入oracle、db2等
  • SAS/ACCESS 连接选项,常用的如用户名,密码等,不同的DMBS数据文件会有所不同
  • SAS/ACCESS 逻辑库选项,控制SAS处理DBMS对象的方式,不同的DBMS数据文件会有所不同

PROC IMPORT语法

PROC IMPORT

DATAFILE = “filename”|DATATABLE = “tablename“(Not used for Microsoft Excel files)

<DBMS = data-source-identifier>

<OUT = libref.SAS data-set-name> \<SAS data-set-option(s)>

<REPLACE>

<file-format-specofoc-statements>;

RUN;

  • filename: 欲读入的文件,包括路径、文件名以及扩展名(如:d:\mydata.xls),当然也可以用之前定义的fileref
  • data source identifier: 一般情况下与文件扩展名一致,.mdb、.dbf、.dat、.sav等。如果是excel文件,建议用Excel
  • <OUT句>: 读入数据后存放的SAS数据库和数据集名称
  • <SAS data-set-option(s)>:对保存的数据进行数据集读写,变量筛选,观测筛选等方面的控制
    • PW=选项加密数据集
    • READ=、WRITE=、ALTER=选项分别加密读、写以及修改权限
    • KEEP=、DROP=、RENAME=选项筛选、重命名变量
    • OBS=、WHERE=筛选保留的观测
  • <REPLACE>: 重复运行时替换掉同名数据集
  • <file-format-specific-statements>: 对分隔符分隔的文件(如CSV文件)、EXCEL文件、Access数据文件、dBase数据文件、Paradox数据文件、SPSS以及Stata数据文件做更详细的读取设置
  • 对于分隔符分隔的文件
    • DATAROW=n 指定数据从第n行开始
    • GETNAMES=YES|NO 应对数据文件首行是不是变量名
    • GUESSINGROWS=n|MAX 应对仅用默认头20行数据无法判断变量类型和长度的情况
    • DELIMITER=‘char’|’nn’x 个性化指定数据文件的分隔符,如DELIMITER=‘#’|‘20’x(十六进制ascii码的空格)
  • 对于EXCEL文件
    • SHEET=EXCEL文件中特定的sheet
    • RANGE=读入某sheet中特定的数据区域

LIBNAME访问PC文件语法

LIBNAME <libref> <engine-name> <‘physical-path and filename.ext’> <SAS/ACCESS-engine-connection-options> <SAS/ACCESS LIBNAME-options>;

  • libref: 逻辑库名,其实是存放数据表和视图的DBMS数据库、架构、服务器端别名
  • engine-name: 引擎名,不同的DMBS数据文件需要指定不同的引擎名,入oracle、db2等
  • ‘physical-path and filename.ext’: PC数据文件地址,文件名以及扩展名,置于引号中
  • SAS/ACCESS 连接选项,常用的如用户名,密码等,不同的DMBS数据文件会有所不同
  • SAS/ACCESS 逻辑库选项,控制SAS处理DBMS对象的方式,不同的DBMS数据文件会有所不同

⚠️SAS在读取Excel文件时,默认用前8行数据判定列的数据类型和长度。解决的办法是让SAS读入更多的数据行再确定数据类型,然而SAS未为Excel提供这样的选项。可以修改Windows注册表的Excel的TypeGuessRows的值为0,这样SAS会在读入所有行后再确定变量的类型。

1
2
3
4
5
6
7
8
9
10
11
filename myexcel "D:\Data\Raw|class.xlsx";
prco import
datafile=myexcel dbms=excel out=myxls replace;
range="'sheet1$A1:E20'n"; /*读入sheet1的A1-E20区域数据*/
getnames=yes;
run;
proc import
datafile=myexcel dbms=excel out=myxls replace;
dbdsopts="firstobs=3 obs=8"; /*读入sheet1的3-8行区域数据*/
getnames=yes;
run;

读入CSV文件

1
2
3
4
5
6
7
filename mycsv "D:\Data\Raw|class.csv";
proc import
datafile=mycsv dbms=csv out=tmp replace;
getnames=yes;
guessingrows=20; /*通过前20行确定变量类型*/
datarow=2; /*数据从第二行开始*/
run;

读入TXT特殊字符分隔的文件

1
2
3
4
5
6
7
8
9
10
11
12
filename mytxttab "D:\Data\Raw|class_tab.txt"
filename mytxtblk "D:\Data\Raw|class_blk.txt"
proc import
datafile=mytxttab dbms=dlm out=tmp replace;
delimiter='09'x;
getnames=yes;
run;
proc import
datafile=mytxtblk dbms=dlm out=tmp replace;
delimiter='20'x;
getnames=yes;
run;

INPUT语句列表读入式

适合数据不齐整

INPUT <pointer-control> variable <$> <:|$|~> <informat.> @|@@;

  • pointer-control: 控制变量读入点起始位置。针对行: #, /。针对列: @, +。
  • variable: 变量列表
  • $: 变量类型为字符型
  • :|$|~: 三个互斥点可选用格式修饰符
    • : 读入点变量列上不齐整,读到空列、读完字符定义的长度或者数据行结尾时就算一个变量读完
    • & 读入点字符变量包含不连续的空格
    • ~ 读入其他分隔符分隔数据,字符变量引号,引号里有分隔符
  • informat.: 输入格式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    data tmp;
    input name : $13. gender $ age location $; /*:表示遇到空格或第13列,才读完name*/
    datalines;
    WYY M 25 Shanghai
    WuYuanyi M 25 Shanghai
    StatsThinking M 1 Beijing
    ;
    run;
    data tmp;
    input name & $9. gender $ age location $; /*一个空格不会认为变量结束*/
    datalines;
    W YY M 25 Shanghai
    Wu Yuanyi M 25 Shanghai
    ;
    run;
    data tmp;
    infile datalines delimiter=',';
    input name & $9. gender $ age location $ affiliation ~ $12.;
    datalines;
    YY WU,M,30,Shanghai,"SHTU,SSIT"
    Yuanyi Wu,M,30,Shanghai,"SHTU,SSIT"
    run;

INPUT语句列读入式

适合数据齐整的情况

INPUT variable<$> start-column<-end-column> <.decimals> @|@@;

  • start-column<-end-column>: 变量读入点起止列
  • .decimals: 小数位数
1
2
3
4
5
6
data tmp;
input name $ 1-9 gender $ 11 age 13-14 location $ 16-23;
YY Wu M 25 Shanghai
Yuanyi Wu M 25 Shanghai
;
run;

INPUT语句格式读入式

可以对字符变量指定宽度,以及读入非标准形式对数字,如科学计数法、带货币符号、带千分位等。

INPUT <pointer-control> variable informat. @|@@;
INPUT <pointer-control> (variable-list) (informat-list) @|@@;
INPUY <pointer-control> (variable-list) (<n> informat.) @|@@;

  • (variable-list) (informat-list): 变量格式列表
    • 编号范围列表:形如x1,x2,x3可缩写为x1-xn
    • 名称范围列表:x–a定义顺序从x到a的所有变量,x-numeric-a为x到a的所有数值型变量,x-character-ax到a的所有字符型变量
    • 名称前缀列表:如x_1,x_2或x1,X2可简写成x:
    • 特殊SAS名列表:_numerica_, _character_, _all_
  • <n> informat.: 变量格式列表n表示格式重复的次数
1
2
3
4
5
6
7
8
data tmp;
/*gender虽然只有1列,但声明时要带上其后的一个空格,age,location类似*/
input name & $10. gender $2. age 2. +1 location $8. fee comma6.;
datalines;
YY Wu M 25 Shanghai 12,345
Yuanyi Wu M 25 Shanghai 54,321
;
run;

INPUT语句命名读入式

INPUT <pointer-control> variable= <$> @|@@;
INPUT <pointer-control> variable= informat. @|@@;
INPUT variable= <$> start-column<-end-column> <.decimals> @|@@;

1
2
3
4
5
6
7
data tmp;
input name= $ gender= $ age= location=$;
datalines;
name=WYY gender=M age=25 location=Shanghai
name=GY gender=F age=24 location=Shanghai
;
run;

数据导出

PROC EXPORT DATA=<libref.>SAS data set<(SAS data set options)>

OUTFILE=”filename”|OUTTABLE=”tablename”

<DBMS=data-source-identifier\>

<LABEL>

<REPLACE>

<file-format-specific-statements>;

RUN;

  • SAS data set: 欲输出的数据集
  • filename|tablename: 输出文件的地址名称
  • LABEL: 输出文件中输出变量名的标签
1
2
3
4
5
6
7
8
9
proc export
data=sashelp.class outfile='D:\Data\Raw|class.xlsx'
dbms=excel replace;
run;
proc export
data=sashelp.class outfile='D:\Data\Raw|class_tab.txt'
dbms=csv replace delimiter='09'x;
run;

行舟来去泛纵横:变量观测

DATA+SET语句

DATA <data-set-name-1 <data-set-options-1>> <…data-set-name-n <data-set-options-n>> </<DEBUG> <NESTING> <STACK = stack-size>> <NOLIST>;

DATA _NULL_ </<DEBUG> <NESTING> <STACK = stack-size>> <NOLIST>;

  • data-set-name: 欲创建的SAS数据集名
  • data-set-options: 欲创建的SAS数据集的限制选项
  • DEBUG: 调试程序逻辑错误以及部分数据错误
  • NESTING: 日志中标记DO-END和SELECT-END语句的起止
  • STACK =: 可嵌套LINK语句个数
  • NOLIST: 出错时不在日志打印每个变量的值
  • _NULL_: 不建任何SAS数据集

获取背后数据

  1. 利用OSD TRACE ON和ODS TRACE OFF对整个统计过程进行全程追踪和监控:
1
2
3
4
5
6
ods trace on;
proc lifetest data=sashelp.bmt;
time t*status(0);
strata group;
run;
ods trace off;
  1. 在LOG文件中,产生的结果一目了然,想要什么数据随意抓取。
  2. ODS OUTPUT语句抓取Result树形目录下结果:
1
2
3
4
5
ods output SurvialPlot=SurvPlotData;
proc lifetset data=sashelp.bmt;
time t*status(0);
strata group;
run;

IF与WHERE

  1. WHERE更高效。WHERE语句在读入PDV之前就先行判断,求子集IF语句先读入观测进入PDV,而后再判断。
  2. WHERE更广泛。WHERE语句可用在DATA步,PROC步,作为数据集选项使用。IF语句只能作为DATA步语句使用。
  3. IF语句对INPUT语句创建的观测有效,WHERE语句只能筛选数据集里的观测。
  4. 当有BY语句时,求子集IF语句与WHERE语句结果可能不同,因为SAS创建BY组再WHERE语句之后,求子集IF语句之前。
  5. 求自己IF语句可以用在条件IF语句中,WHERE语句不行
  6. 当读入多个数据集时,WHERE语句可以针对每个数据集单独筛选,求子集IF语句不行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*打开数据集时,直接读取只需要的观测:通过WHERE选项限定读入数据集*/
data tmp;
set sashelp.class(where=(sex="F"));
run;
/*PDV里筛选过滤观测*/
/*通过WHERE语句*/
data tmp;
set sashelp.class;
where sex="F";
run;
/*通过求子集IF语句*/
data tmp;
set sashelp.class;
if sex="F";
run;
/*只写入所需观测进入数据集:通过WHERE选项限定输出数据集*/
data tmp(where=(sex="F"));
set sashelp.class;
run;
data want(where=(not missing(id)));
set raw1(where=(age between 20 and 30)) raw2(where=(sex="F"));
run;

KEEP、DROP与RENAME

  1. 选项只作用于被其尾随的数据集,而语句作用域PDV,即语句对不管来自哪个数据集的变量都有效。
  2. KEPP/DROP,RENAME,WHERE和其他语句的执行有固定的执行顺序。
    • 数据集读入和输出阶段的执行顺序:
      1. KEPP/DROP选项筛选变量
      2. RENAME选项修改变量名
      3. WHERE选项筛选观测
    • 编程处理阶段:
      1. WHERE选项筛选观测
      2. 其他执行语句
      3. KEPP/DROP选项筛选变量
      4. RENAME选项修改变量名

编译变量和临时变量

编译变量(NOBS、IN、OBS、END、POINT等)和临时变量的赋值方式是将等号左边赋值给等号右边,其他赋值语句是将等号左边赋值给右边,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*PROC SQL获取观测值 最慢*/
proc sql;
select count(name) as N from sashelp.class;
quit;
/*_N_获取观测数 中*/
data _null_;
set sashelp.class end=last;
if last then put _n_;
run;
/*编译变量获取观测数 最快*/
data _null_;
if 0 then set sashelp.class nobs=n;
put _all_;
run;

CALL例程

CALL例程也可以生成新变量,这种方法是函数形式的一种变种。

1
2
3
4
5
6
7
8
9
10
data rand;
seed=123;
do i=1 to 10;
x=rannor(seed);
call rannor(seed,y);
output;
end;
run;
proc print data=rand;
run;

变量类型转换

new_variable = input(original_variable, informat.);

new_variable = put(original_variable, format.);

  • new_variable:欲生成的新变量
  • informat.:变量输入格式
  • format.:变量输出格式

DATA步实现累加

累加语句:variable+expression;

  • variable:累加器变量,必须为数字型变量,累加后的值保存于此变量中
  • expression:表达式,表达式的值会被累加到累加器变量variable中
1
2
3
4
5
6
data want;
set sashelp.class;
cum_weight+weight;
cnt_weight+1;
avg_weight=cum_weight/cnt_weight;
run;

RETAIN语句:RETAIN <element-list(s) <initial-value(s)|(initial-value-1)|(initial-value-list-1)> <…element-list-n <initial-value-n|(initial-value-n)|(initial-value-list-n)>>>

  • element-list:需要保留PDV里的值的参数,可以是变量名、变量列表、数组名
  • initial-value:初始值,对应于只有一个参数或者参数列表里的第一个参数
  • (initial-value-1):带括号的初始值
  • (initial-value-list-1):带括号的初始值列表
1
2
3
4
5
6
7
data want;
set sashelp.class;
retain cum_weight cnt_weight (0 0);
cum_weight=cum_weight+weight;
cnt_weight=cnt_weight+1;
avg_weight=cum_weight/cnt_weight;
run;

BY语句的作用是在PROC SORT中排序后,在SET、MERGE、UPDATE以及MODIFY语句中,指定分组变量,产生临时变量FIRST.变量和LAST.变量用以标示观测变量是否为分组变量里的第一条和最后一条。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
proc sort data=sashelp.class out=class;
by sex;
run;
data want;
set class end=last;
by sex;
if first.sex then do;
cum_weight=0;
cnt_weight=0;
end;
cum_weight+weight;
cnt_weight+1;
if last.sex then do;
avg_weight=cum_weight/cnt_weight;
output;
end;
run;

隔行取数据

SAS DATA步是隔行处理数据,一旦一行处理完,读入下一行数据后,前面行的数据就不在PDV里了。

  • LAG:把前面任一行的数据在取出来
  • DIF:计算目前行与前面任一行的差
1
2
3
4
5
6
7
8
9
10
11
data want;
set sashelp.class;
/*前面2人是谁*/
pre1name=lag1(name);
pre2name=lag2(name);
/*与前面两人身高的差*/
dif1height=dif1(heigh);
dif2hegith=dif2(height);
run;
proc print'
run;

网贷黑中介调研

Posted on 2017-08-02 | In Loan

最近进入了互联网金融行业,继续做一些反欺诈相关的工作。知己知彼,百战不殆。

网贷技术

准备工作

客户的详细版征信

不查征信的小贷,另当别论。要求客户打印详细版征信;没有的话,一定要让客户如是交代最近的申请记录以及单位信息。

删除贷款相关信息

  • 贷款App:删除客户手机里所有贷款相关的App
  • 手机短信:删除所有信贷相关的短信,包括网贷平台的验证码、批准、被拒短信;信用卡催收短信,包括带有“如已还款请忽略”的。
  • 通话记录:删除一切与信贷公司、银行相关的通话记录。更不可将号码保存到通讯录。
  • 信用卡账单:删除逾期账单、未满六个月的信用卡的账单、非详版账单,只保留符合要求且用卡状况良好的账单。
  • 淘宝交易记录:删除充值点卡、购买虚拟物品,非客户本人收货地址、收货人电话与申请人不一致的交易。

包装客户

年龄、学历、单位、公积金、社保、征信情况、车贷、房贷、信用卡种类、贷款记录、打卡工资、是否有保单、实名制手机、芝麻分、电商账号。

  • 年龄:一般18-60周岁,大部分网贷已经限制到22-40周岁。
  • 征信:纯白户或黑户,做黑白户小贷的口子。
  • 信用卡:3-6月或以上的客户,大部分口子都可以操作。
  • 账单:一些口子要6个月以上的连续账单,如叮当贷、爱钱进、宜人极速贷。
  • 车贷、房贷:可以做易分期,也可以办卡。办卡的话,基本上都可以下。
  • 保单:平安人寿的保单贷、太平洋的保单贷。
  • 社保、公积金:有地区限制,51公积金app,宜人贷公积金模式、网易小贷。
  • 学历:浦发青春贷、闪银,交通、光大办信用卡。
  • 在校大学生:本科学历可以做10-50万贷款。

贷款实操

  • 单位好直接使用,无单位就要包装单位。
  • 做工牌认证、银行流水账单。
  • 培训客户,做好回访。
  • 坐等下款,收钱。

申请贷款的10个细节

  • 实名制手机:每个月必须有通话记录,证明这个电话是经常使用的。
  • 联系人:必须能在最近通话记录中找到的联系人。
  • 工作信息:很多网贷会共享资料,因此工作信息不要经常换,最好提供一年以上的。如果没有工作,自己准备一个固话,搜索附近的公司(网上没电话的那种),用这家公司的名字在网上发布招聘信息,留下准备的固化。当然工作合同证明也可以这样。
  • 信用卡账单邮箱:账单必须连续多月,若有多张信用卡,保留信用最好的一张卡就行。
  • 阿里系验证:淘宝支付宝一定要实名验证,最近两个月一定要有实物消费记录。保留一个常用地址,其他全部删除。
  • 工作证明、名片、工牌:
  • 回访电话:一定要接到电话,有的网贷公司两次没接到就会直接拒。回答问题一定不要犹豫,必须和资料相符。
  • 回访联系人:回访联系人的网贷不是很急不用去申请。申请前对手机里的联系人进行整理,并提前打好招呼。
  • 回访内容
    • 父母:
    • 公司:本人接最好,本人没接到,一定要让接电话的人说是单位电话。
    • 配偶:一定是本人接听,不是本人则100%拒贷。
    • 申请人:聊工作,聊生活,也可以反问能否批,什么时候批。
  • 信用卡回访
    • 资料写小纸条上,随身携带以免忘记。
    • 不清楚如何回答时,借口信号不好,过几分钟再打来,趁机熟悉资料。
    • 卡片寄哪里?一定要寄往资料上的公司或住址。
    • 要和申卡时填写的联系人提前说明,以免挂掉。
    • 问认识单位谁谁谁时,若不认识,可回答“或许有,公司人多不熟悉”。

不上征信的小贷

宜人贷、功夫贷、拍拍贷、信用钱包、发薪贷、现金巴士、亲亲小贷、达飞云贷、手机贷、小花钱包贷、闪电借款、用钱宝、你我贷、指尖贷、曹操贷、积木盒子、麦芽贷、闪银、名校贷、神灯小贷、玖富叮当贷、么么贷、魔法现金、给你花、屌丝贷、51人品贷、融360、月光足

上征信的贷款

微粒贷(深圳前海微众银行)、借呗(网商贷)、捷信(中银、北银、马上)、消费金融、佰仟金融(哈尔滨银行)、省呗(包商银行)、拉卡拉、卡卡贷、贷款王、证大、中安信业、平安、布丁小贷、豆豆钱、唯信旗下系列产品、信而富现金贷、马上金融、安逸花

不查征信的网贷

手机贷、发薪贷、信用钱包、现金巴士、拍拍贷、人人贷、信闪贷、用钱宝、鼎及贷、mo9、曹操贷、亲亲小贷、原子贷、闪银、嗨秒贷、闪电借款、钱站、读秒、我来贷、指尖贷、小花钱包、小米金融、么么贷、魔法现金贷、给你花、趣借吧、玖富叮当贷、功夫贷、达飞云贷、51人品贷、58消费金融、融360、月光足、信而富现金贷

无视黑白的贷款

拍拍贷、现金巴士、手机贷、马上金融、父母贷、发薪贷、闪银奇异、平安普惠、我来贷、给你花、信闪贷、贷款王、用钱宝、鼎及贷、mo9、曹操贷、亲亲小贷、原子贷、嗨秒贷、微信马上贷

信用卡口子

卡卡贷、闪电借款、钱站、宜人贷、省呗、积木盒子、读秒贷、你我贷-嘉卡贷、功夫贷、51人品贷、小赢卡贷、还呗

公积金口子

  • 江苏银行app:金E融 (地区限制:江苏)
  • 51公积金app:很多公积金贷款通道
  • 网易小贷:微信关注
  • 你我贷app:嘉英贷
  • 宜人贷app:公积金模式
  • 中信银行公积金贷款:网银申请,公积金缴存两年以上
  • 有鱼公积金app:公积金缴存6个月以上

防止银行降额封卡和冻结的方法:

  • 预约分期(打电话给银行客服,这比消费预约3-6期的分期)
  • 全额还款
    • 账单日和最后还款日的修改功能
    • 最后还款日后已经开始收利息了
    • 免息天数 = (最后还款日 - 账单日)[20天] + 银行宽限期限[2-3天]
  • 选择五台不同商户的POS机(一机一码),五台一组,一天两到三次,循环的刷出来再循环的还进去。分10笔或者11笔,周期为10天。最后还款日前三天完成。甚至有可能提升额度。

消除不良记录

  • 银行有征信更新的权限
  • 银行权限内,自己都可以处理
  • 银行权限外,谁都不行

三类人群

  • 有信用卡,有申请记录,征信报告有记录
  • 有在银行递交过申请资料
  • 三无人员,无向银行递交申请资料,无网贷

中国建设银行

优质客户办卡

  1. 申请一张建设银行龙腾理财金卡(要求开通网银,获得U盾、密码器)
    • 功能:贷卡合一、理财、储蓄
    • 条件:存五万
    • 漏洞:小城市小网点可以免费办理
  2. 把所有钱都集中到建设银行
  3. 购买建设银行的理财(速盈理财)
  4. 购买速盈理财7天,产生一个周期的收益。7天后收到短信“您是我行理财优质客户,邀请申请龙卡JOY”。如果没有收到短信,把理财的钱取出来,再买一个周期。

建设银行代发工资、团办申卡

有公司的人[代发工资业务]

  • 条件
    • 必须有公司正常营业,正常注册时间越久越好
    • 人数:30人左右(各地人数不一样)
    • 被代发人必须在建设银行具有储蓄卡
    • 代发金额:3600 - 8000
    • 代发时间:6-12个月
    • 每月代发时间:给员工发工资的前一天,把代发的钱打入银行代发账号
    • 代发费用:建设银行每个人4-5元
  • 申请代发金额的1.5-2倍的信用卡。10个人,每人代发3600,下个月每人可申请3万的信用卡。公司就有30万可以使用。
  • 工资袋最高额度30万

白户

  • 众筹:筹人、筹资金、筹公司。然后按第一种方法。

有建设银行ETC信用卡的人

区县换卡

建设银行实操

  1. 下载中国建设银行客户端
  2. 绑定龙腾理财金卡的手机注册登陆
  3. 买入速盈理财7天,直到收到邀请短信。
  4. 信用卡管理页面中可以看到预审批额度查询。如果额度低,循环买卖理财。
  5. 信用卡管理页面中找到卡片推荐,35岁以下的龙卡JOY。

造假

  • 工作
    • 挂靠熟人公司
    • 自行挂靠:借助企信宝、天眼查
  • 座机
    1. 找移动联通购买座机
    2. 招淘宝做彩铃
    3. 淘宝买座机绑定手机呼叫转移
  • 住宅
    • 借助58同城、赶集网
  • 控卡 异地挂靠申请

提额

绑定建设银行的手机,打95533。转2号线,嘟一声立刻挂断。编辑短信CCTE#卡号后四位#额度的两倍发送到95533。

交通银行第三次融资

  1. 微信添加“交通银行信用卡|买单吧”公众号
  2. 点击“方便用”-“分期借款”-“好享贷”-“登录”
  3. 有缘分告诉你怎么刷爆好享贷

    怎么使用

  • 分6-12期。分期越久,提额周期越久,风控风险越高。
  • 3-5台pos机将固定额度刷出来;好享贷分到固定额度,再多笔刷出来
1…3456

Yuanyi Wu

朝闻道 夕死可矣

29 posts
9 categories
30 tags
GitHub FB Page
© 2019 Yuanyi Wu
Powered by Hexo
|
Theme — NexT.Mist v5.1.2