分类 sas 下的文章

前言

前几日,于一月底在家闲的实在无聊,便找了点事情做,写了个小脚本每小时收集实时疫情信息,并保存到数据库中,到我写这篇文章为止,我已经收集到了241396条数据,精确到了地级市的确诊人数、治愈人数、死亡人数,大多数小伙伴们都于下周一返回工作岗位进行复工,下面我将用数据告诉你,为什么国家在下周一敢让你复工。

导入数据

将mysql数据库中的数据导出csv,保存到桌面,记住路径,用sas导入到临时work库中:

filename csvfile '/folders/myfolders/data_files/all_data.csv';

proc import datafile=csvfile
    dbms=csv
    out=work.import;
    getnames=yes;
    guessingrows=32767;
run;

导入的数据集信息如下:

  • confirmedCount:确诊人数
  • curedCount:治愈人数
  • deadCount:死亡人数
  • name:省份、地级市名称
  • parent_id:上级地区名称
  • update_time:更新时间

数据清洗

  • 由于数据源suspectedCount(疑似人数)不正确,需要在数据集里丢掉它
  • update_time的格式是datetime,需要把相关日期提取出来,把时间去掉
  • 需要从时间把时提取出来,方便后面作筛选
data sasr_all_data;
    set work.import;
    datetime = datepart(update_time);
    hour = hour(update_time);
    format datetime yymmddn8.;
    drop suspectedCount update_time;
run;

数据筛选、计算

以湖北省为例

数据筛选

由于湖北省是疫情重灾区,数据量较大,更容易看出疫情蔓延的趋势,所以我们首先将湖北省截止到我写文章的时间点数据(20点)拿出来:

data hubei_data;
    set work.sasr_all_data;
    where datetime between input('2020-01-29',yymmdd10.) 
    and input('2020-02-20',yymmdd10.)
    and hour = 20
    and name = '湖北省';
    drop parent_id;
run;

数据计算

计算每日确诊人数、死亡人数、治愈人数的增长率

data hubei_data_handle;
    set work.hubei_data;
    
    /*新建三个变量来保存数据上次迭代的数据*/
    retain confirmed_temp cured_temp dead_temp;
    
    /*计算增长率*/
    confirmed_growth_rate = abs(confirmed_temp - confirmedCount) / confirmed_temp;
    cured_growth_rate = abs(cured_temp - confirmedCount) / cured_temp;
    dead_growth_rate = abs(dead_temp - confirmedCount) / dead_temp;
    
    /*为临时变量赋值*/
    confirmed_temp = confirmedCount;
    cured_temp = curedCount;
    dead_temp = deadCount;
    
    /*为缺失值赋值为0*/
    if confirmed_growth_rate = . then confirmed_growth_rate = 0;
    if cured_growth_rate = . then cured_growth_rate = 0;
    if dead_growth_rate = . then dead_growth_rate = 0;
run;

在进行完数据计算之后,接下来就是图形展示:

图形可视化分析

我们先看一下湖北省每日的死亡人数和确诊人数:

title "湖北省疫情感染情况图";
proc sgplot data=hubei_data_handle;
  xaxis type=discrete;
  series x=datetime y=confirmedCount / datalabel;
  series x=datetime y=deadCount / 
      datalabel y2axis;
run;
title;

从折线图看,每日增长在逐渐变缓,在02月12日湖北省感染人数明显增长,原因是在12日这天新的领导班子,将之前掩盖的问题彻底揭露了出来,经过新的领导班子的铁腕政策,拐点快要到来,下面看一下死亡人数、确诊人数的增长率:

title "湖北省疫情增长率情况图";
proc sgplot data=hubei_data_handle;
  xaxis type=discrete;
  series x=datetime y=confirmed_growth_rate / datalabel;
  series x=datetime y=dead_growth_rate / 
      datalabel y2axis;
run;
title;

红色线条是死亡增长率,从02月05日开始,死亡率明显下降,同时在12日有了突增,原因还是因为新的领导班子大刀阔斧,将之间旧的问题暴露出来,从12日开始,增长率开始有了明显的下降,蓝色线条是确诊人数增长率,我们也看到了明显的下降,疫情有了明显的控制。

以全国为例

数据筛选

首先需要拿出全国省市在01月29日至02月20日特定时间点(20点)的数据:

data all_data;
    set work.sasr_all_data;
    where datetime between input('2020-01-29',yymmdd10.) 
    and input('2020-02-20',yymmdd10.)
    and hour = 20
    and parent_id = 'NULL';
    drop parent_id;
run;

数据计算

将数据按照日期汇总,计算出全国总的确诊人数、死亡人数、治愈人数:

proc sql;
    create table all_data_sum as
    select t.datetime,
        sum(t.confirmedCount) as confirmedCount,
        sum(t.deadCount) as deadCount,
        sum(t.curedCount) as curedCount
        from all_data t group by t.datetime;
quit;

计算增长率,计算逻辑与之前相似:

data all_data_handle;
    set all_data_sum;
    retain confirmed_temp cured_temp dead_temp;
    confirmed_growth_rate = abs(confirmed_temp - confirmedCount) / confirmed_temp;
    cured_growth_rate = abs(cured_temp - confirmedCount) / cured_temp;
    dead_growth_rate = abs(dead_temp - confirmedCount) / dead_temp;
    confirmed_temp = confirmedCount;
    cured_temp = curedCount;
    dead_temp = deadCount;
    if confirmed_growth_rate = . then confirmed_growth_rate = 0;
    if cured_growth_rate = . then cured_growth_rate = 0;
    if dead_growth_rate = . then dead_growth_rate = 0;
run;

图形可视化分析

首先看一下全国的每日死亡人数和确诊人数:

title "全国疫情详情统计图";
proc sgplot data=all_data_handle;
  xaxis type=discrete;
  series x=datetime y=confirmedCount / datalabel;
  series x=datetime y=deadCount / 
      datalabel y2axis;
run;
title;

虽然曲线在逐渐增长,但是斜率在逐渐变低,那就意味着增长率也在慢慢降低。

接下来看一下增长率:

红色线条是死亡增长率,蓝色线条是感染人数增长率,我们可以明显看到,每日感染人数的增长率都在逐步降低,死亡率也在慢慢降低,疫情得到了明显的控制,增长率已经控制到了2%以下。

总结

通过全国和湖北重灾区数据的可视化分析,我们能够得到的一个结论是,我们的各项数据的增长率在慢慢降低,相信不久的将来,可能是10天以内,增长率会控制在1%以下,这就为全国复工打下了坚实的基础,所以国家才会大力鼓励各地全员开工,恢复经济发展,好了今天的文章就到这里,下面是我的个人微信公众号,如果这篇文章帮到了您,请右下角点一个在看支持我一下,我们下期再见!我是TyrantLucifer,一个专注于Linux、Python、数据挖掘、数据分析的初入门小菜鸡~~

前言

目前项目进行到中期,最近又学习了一些新的知识,例如sas拼表、导出文件、数据集筛选等,好记性不如烂笔头,记录下来有待后期回头查看,人生总是走在学习的道路上。

SAS 导出文件

SAS将数据集导出为文件有两种方法,一种使用PROC EXPORT,另外一种是使用DATA

  • proc export
PROC EXPORT DATA=DATA_SET OUTFILE="/sas/data_set.txt" DBMS=TAB REPLACE;
DELIMITER="|";
PUTNAMES=NO;
RUN;
/*
    DATA:指定要导出的数据集
    OUTFILE:指定要导出的文件
    DBMS:指定导出文件类型,文本文件为TAB CSV文件为CSV
    REPLACE:文件覆盖选项
    DELIMITER:指定文件的分隔符
    PUTNAMES:指定是否输出表头
*/
  • data
FILENAME DATA_SET "/sas/data_set.txt";
DATA _NULL_;
SET DATA_SET;
FILE DATA_SET LRECL=32767 DLM="|" ENCODING="UTF-8" TERMSTR=CRLF;
PUT
NAME AGE CLASS_NAME;
RUN;
/*
    LRECL:指定读入记录的长度,默认是256
    DLM:指定分割符
    ENCODING:指定文件编码
    TERMSTR:指定记录分隔符
*/

SAS 数据集筛选

  • WHERE子句进行筛选

SAS 数据集筛选可以在DATA步中进行操作,使用WHERE关键字对指定的列的值进行条件筛选,例子如下:

DATA STUDENT;
SET STUDENT;
WHERE AGE <= 10;
RUN;
  • KEEP关键字

KEEP关键字可以使数据集保留下你想要的字段,比如一个表里边有五个字段,你只想保留三个字段,则使用KEEP关键字进行过滤

DATA STUDENT;
    SET STUDENT;
    KEEP 字段1 字段2 字段3;
RUN;
  • DROP关键字

DROP关键字可以丢掉你不想要的字段

DATA STUDENT;
    SET STUDENT;
    DROP 字段1 字段2 字段3;
RUN;
  • 另外的写法
DATA STUDENT;
    SET STUDENT(KEEP=);
RUN;

DATA STUDENT;
    SET SUTDENT(DROP=);
RUN;

DATA STUDENT;
    SET STUDENT(WHERE=);
RUN;

SAS 循环语句格式

DATA _NULL_;
    IF CONDITION THEN ACTION;
RUN;

DATA _NULL_;
    IF CONDITION THEN DO;
        ACTION;
        ACTION;
        ACTION;
    END;
RUN;

DATA _NULL_;
    IF CONDITION THEN ACTION;
        ELSE IF CONDITION THEN ACTION;
        ELSE IF CONDITION THEN ACTION;
        ELSE IF CONDITION THEN ACTION;
    ELSE CONDITION THEN ACTION;
RUN;

SAS 拼表

SAS 拼表过程十分简单,拼表意思就是表A和表B有共同的列,将表根据相同的列拼在一起,跟SQL中的left join和right join还有inner join是一个道理,在拼表之前需要将数据集根据公共的字段排序,需要用到PROC SORT,下面介绍一下PROC SORT

  • PROC SORT
PROC SORT DATA=STUDENT NODUPKEY DUPOUT=;
BY 字段名1 字段名2 字段名3;
/*PROC SORT 默认会根据第一个字段排序,然后第二个,第三个*/
RUN;

/*
    NODUPKEY:关键字可以实现去重功能
    DUPOUT=数据集名称:可以实现将重复的数据放在指定的数据集中
    BY DESCENDING:默认以升序排序,用了DESCENDING关键字则以降序排序
*/
  • MERGE
/*left join*/
DATA STUDENT;
    MERGE A(IN=A) B(IN=B);
    BY NAME;
    IF A;
RUN;
/*right join*/
DATA STUDENT;
    MERGE A(IN=A) B(IN=B);
    BY NAME;
    IF B;
RUN;
/*inner join*/
DATA STUDENT;
    MERGE A(IN=A) B(IN=B);
    BY NAME;
    IF A AND B;
RUN;

/*
    MERGE:表A(IN=A) 表B(IN=B)
    BY 后面跟两个表共有的主键
    IF 后面跟表关联关系
*/

前言

包括实习和入职,在SAS中国也已经待了有一段时间,经过这么久的熏陶我对SAS语言还不是很熟悉,平时的时间也没有太过深入的去进行学习SAS语言,前几天去中国银行客户现场,也总算接触到了一点SAS语言的皮毛,今天就算是一个引子吧,准备在博客开一个学习SAS语言的专栏,一是来记忆一下学到的知识点,俗话说好记性不如烂笔头,二是积累一下自己的技能,为后面的工作做铺垫,人生总是走在学习的路上。

SAS数据集、变量、常量、观测

  • 数据集:SAS可以管理的结构化数据,简单来说就是SAS软件认识的数据表,可以过程步用来数据处理,数据建模,如果说你的数据是外部文件保存,需要用SAS语言进行处理之后变成SAS数据集

    • 数据集的名称不超过32个字符
  • 变量:简单来说就是表头,数据表每一个数据项的名称就是一个变量

    • 类型:数值型和字符型(变量名后带$)
    • 特性:名称、类型、长度、输入格式、输出格式、标记
    • 最多有32个字符组成,由字母、数字、下划线组成
    • 长度默认为8
  • 常量:固定不变,跟其他编程语言类似
  • 观测:简单来说就是表的一行数据,在SAS里称之为观测

SAS导入数据的几个方法

  • 图形化界面导入(在数据不大的时候可以去用图形化界面进行导入,这里不过多赘述)
  • SAS代码导入

本次工作的目标

本次的工作目标是用SAS脚本把客户的外部数据导入到SAS软件中

SAS代码导入实例

  1. 导入内部数据,也就是sas代码中定义的数据,使用datalines关键字
data test;
    input name $ sex $ age;
    datalines;
    tom    男 23
    jim    女 24;
run;
  1. 导入txt文件数据
tom    男 23
jim    女 24

假设txt文件内容如上图所示,分隔符为空格

data test;
    infile "/home/sas/test.txt";
    input name $ sex $ age;
run;
tom/男/23
jim/女/24;

假设txt文件内容如上图所示,分隔符为/

data test;
    infile "/home/sas/test.txt" dlm='/';
    input name $ sex $ age;
run;

dlm这个参数可以指定分隔符,但前提是分隔符只有一个字符,如果分隔符是多个字符的话,则需要用dlmstr参数指定

姓名 性别 年龄
tom    男 23
jim    女 24

假设txt文件内容如上图所示,第一行有表的变量名称,我不想读进去,这时候用firstobs这个参数,指定SAS从哪一行开始读,同时obs这个参数还可以控制读到多少行

data test;
    infile "/home/sas/test.txt" firstobs=1;
    input name $ sex $ age;
run;
姓名 性别 年龄
tommmmmmmmmmmmmmmmmmmmmm 男 23
jimmmmmmmmmmmmmmmmmmmmmm 女 24

假设txt文件内容如上图所示,姓名已经超过了默认的8个长度,为了完整的导入数据,这时我们可以用length这个关键字,去进行定义这个变量的长度,或者在input语句中使用:去定义长度,所以代码可以是这样

data test;
    infile "/home/sas/test.txt" firstobs=1;
    length name $20.;
    input name $ sex $ age;
run;

或者是这样

data test;
    infile "/home/sas/test.txt" firstobs=1;
    input name:$20. sex $ age;
run;

在最后介绍一下另外的两个关键字missoverdsd

missover的作用是,如果txt文件一行数据不够时,告诉sas不要跳到下一行进行读取,简单来说就是保证读取数据不会串行

dsd的作用是,忽略用引号括起来数据中的分隔符,假设数据是用,进行分割,数据项是china,beijing,为保证该行数据能完整被读入,需要使用dsd

SAS执行Linux命令,并返回命令执行的结果

sas比较强大的地方就是可以无缝与shell进行集成衔接,这样你就可以使用shell获取到的结果进行数据处理与分析,可用到的场景非常之多,举一个例子,在sas进行io测试的时候,我们可以图形化界面显示出io测试的结果和数据,后期尝试写一个脚本出来,可以提高以后的工作效率。

 
示例代码如下:
filename cmd pipe "ls /home/sas";
data _null_;
infile cmd;
input result:$200.;
run;

未完待续

本次只是提到了txt文件,后续还有csv、excel文件,下次更新~~~