《深入解析sas:数据处理、分析优化与商业应用》一3.3 创建新变量

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介:

本节书摘来自华章出版社《深入解析sas:数据处理、分析优化与商业应用》一书中的第3章,第3.3节,作者 夏坤庄 徐唯 潘红莲 林建伟,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.3 创建新变量

在对SAS数据集进行处理时,经常需要根据原有变量或变量值生成新变量。根据要实现功能的不同,SAS提供了多种方法,例如通过数据集选项RENAME=(RENAME语句)、赋值语句、求和语句等来实现不同的功能。

3.3.1 数据集选项RENAME=和RENAME语句

在DATA步中,可使用数据集选项RENAME=或RENAME语句修改一个或多个变量的名称。跟前面介绍过的数据集选项KEEP=和DROP=一样,数据集选项RENAME=也可用于DATA语句中的输出数据集和SET语句中输入数据集。其基本形式如下:

RENAME=(旧变量名-1=新变量名-1 <...旧变量名-n=新变量名-n >)
RENAME语句的基本形式如下:
RENAME 旧变量名-1=新变量名-1 <...旧变量名-n=新变量名-n >;

其中:
旧变量名指定在输入数据集中或当前DATA步中新创建的变量。
新变量名指定在输出数据集中使用的变量名或变量名称列表。新的变量名仅被写入输出数据集。
数据集选项RENAME=或RENAME语句可以修改多个变量的名称。
例3.17:将数据集saslib.contact2中的变量Name重命名为Full_Name,并将原有Name中的姓和名分开为Last_Name和First_Name。
下面3段代码分别在SET语句中使用数据集选项RENAME=、在DATA语句中使用数据集选项RENAME=和使用RENAME语句来实现。
代码1:

data work.contact2_rn;
    set saslib.contact2 (rename=(Name=Full_Name));
    First_Name=scan(Full_Name,1);
    Last_Name=scan(Full_Name,2);
run;

代码2:

data work.contact2_rn (rename=(Name=Full_Name));
    set saslib.contact2;
        First_Name=scan(Name,1);
    Last_Name=scan(Name,2);
run;

代码3:

data work.contact2_rn ;
    set saslib.contact2;
    rename Name=Full_Name;
    First_Name=scan(Name,1);
    Last_Name=scan(Name,2);
run;

这3段代码中都使用了SCAN函数,将原Name变量中用空格隔开的姓和名提取到变量Last_Name和First_Name中。注意,在引用原Name变量进行操作时,代码1使用了新变量名(Full_Name)、代码2和代码3使用了旧变量名(Name)。这是因为在SET语句中使用选项RENAME=时,SAS为输入数据集所创建的PDV中的变量名就成为了新变量名,所以在编程语句中引用原变量时必须使用新的变量名。但是如果在DATA语句中使用选项RENAME=或RENAME语句,新变量名仅会写入输出数据集,所以在DATA步的其他语句中引用该变量时,必须使用旧的变量名。
PRINT过程打印3段代码的输出数据集work.contact2_rn的内容相同,如图3.20所示。

image

在SET语句中使用数据集选项RENAME=、在DATA语句中使用数据集选项RENAME=和使用RENAME语句的比较如下:
RENAME语句不能用于PROC步,但是数据集选项RENAME=可以。
数据集选项RENAME=可以对每个输出数据集的变量单独更改名称,而RENAME语句修改的变量名称对所有输出数据集都起作用。
SET语句中的数据集选项RENAME=会修改变量名,此时,在编程语句中引用原变量时必须使用新的变量名;如果在输出数据集中使用RENAME=选项或使用RENAME语句,在编程语句引用原变量时必须使用旧的变量名。

3.3.2 赋值语句创建新变量

在DATA步中出现的变量,如果不属于输入数据集的变量,而且也不是自动变量,SAS则会为其创建新变量,所创建的新变量默认会写入输出数据集。可以通过前面介绍的数据集选项DROP=、KEEP=、DROP语句、KEEP语句保留或删除不需要的中间变量。
赋值语句是常见的创建新变量的方法,通常将新变量放在赋值语句的等号(=)左侧来创建新变量,并同时给该变量赋值。在前面的例子已经看到了使用赋值语句修改已经存在的变量值(例3.8~例3.12)和创建新变量(例3.17)。
例3.18:数据集saslib.revenue_quarter中存储了公司产品今年不同季度的销售额,年底要计算全年的总销售额。
该数据集在VIEWTABLE窗口中打开如图3.21所示。

image

下面对各季度的销售额(Rev_Q1、Rev_Q2、Rev_Q3和Rev_Q4)相加得到总销售额Total_Rev,最后使用FORMAT语句修改其输出格式。

data work.revenue;
    set saslib.revenue_quarter;
    Total_Rev = Rev_Q1 + Rev_Q2 + Rev_Q3 + Rev_Q4;
    format Total_Rev DOLLAR10.;
run;

所生成的数据集work.revenue在VIEWTABLE窗口中打开如图3.22所示。该数据集包含了表示全年总销售额的变量Total_Revenue。

image

3.3.3 对多个观测求和

对数据集进行处理时,经常会需要获得整个数据集中的所有观测或特定一部分观测中的变量值的总和,例如,公司所有产品的总销售额、产品在各地区的总销售额等。在DATA步中,可使用求和语句、RETAIN语句、SUM函数等方式对多个观测中的变量值进行求和。
1.?求数据集中变量的总和
求和语句的基本形式如下:

变量+表达式;

其中:
变量指定累加变量的名称,该变量包含一个数字值。
表达式是任意的SAS表达式。当迭代中表达式的值为缺失值时,SAS会将表达式的求值结果当作0处理。
SAS在读取第一个观测前将求和语句中的累加变量的初始值设置为0。如果要将求和变量的初始值设置为其他的值,可使用RETAIN语句(后面介绍)。
在每次迭代中,SAS执行该语句时将表达式的值与该变量的值相加,结果保持在该累加变量中,下次迭代时仍然可以使用。在一次迭代中,当表达式不为缺失值时,求和语句等同于赋值语句“变量=变量+表达式;”。在求和语句中,当表达式为缺失值时,SAS将表达式的值当作0处理,而赋值语句不会这样。
例3.19:读入公司销售数据建立数据集,并计算总销售额。
公司所有员工销售数据所在外部数据文件sales.dat的内容如下:

ET001,Kevin Lee,TSG,$10000
ED002,Faith May,CSG,$12000
ET004,Jackson Cook,TSG,$18000
EC002,Hailey Leonard,CSG,$23000
ED004,Jack Smith,QSG,$5000

为了让所生成的数据集中的变量Sales和Total_Sales的输出格式同输入格式一样,在DATA步使用FORMAT语句指定变量Sales和Toal_Sales的格式为DOLLAR10.。关于FORMAT语句本书第5章会介绍。

filename exfiles "c:\sas\data";
data saslib.sales;
    length Name $20;
    infile exfiles(sales) dsd;
    input Emp_ID $ Name $ Dept $ Sales:COMMA10.;
    format Sales DOLLAR10.;
run;

data work.sales_sum;
    set saslib.sales;
    Total_Sales+Sales;
    format Total_Sales DOLLAR10.;
run;

proc print data=work.sales_sum noobs;
run;

PRINT语句打印所生成的数据集数据如图3.23所示。其中,变量Toal_Sales为前面所有观测中变量Sales值之和。
例3.20:计算公司所有销售人员的总销售额。与上例不同的是,销售数据中存在缺失值。
包含缺失值的数据集的内容如图3.24所示。
使用求和语句对Sales变量进行求和的代码如下:

data work.sales_sum;
    set saslib.sales2;
    Total_Sales+Sales;
    format Total_Sales DOLLAR10.;
run;

对Sales求和后得到的数据集如图3.25所示。因为第三条观测中的Sales为缺失值,求和语句将其当作0处理,所以第三条观测的Total_Sales值与第二条相同。
     
image

2.?求每个BY组的总和
前面提到过,SAS会为BY语句中指定的每个变量生成临时变量FIRST.变量和LAST.变量。在分组数据中,可以使用这两组临时变量计算每个分组中变量值的总和。
例3.21:数据集sashelp.shoes中的观测已经按照地区(Region)、附属品牌(Subsidiary)进行了排序。现在分别计算各地区各附属品牌的销售额总和。
代码如下:

data work.shoes_subsidiary (drop=Sales);
    set sashelp.shoes (keep=Region Subsidiary Sales);
    by Region Subsidiary;

    if First.Subsidiary then
        Total_Sales_Subsidiary=0;

    Total_Sales_Subsidiary+Sales;

    if Last.Subsidiary;

    format Total_Sales_Subsidiary DOLLAR10.;
run;

代码说明如下:
在SET语句中,数据集选项KEEP=指定仅读取输入数据集中的变量Region、Subsidiary和Sales。
在BY语句中,指定BY变量Region和Subsidiary。要求SET语句中的数据集已经按照Region和Subsidiary排序。SAS自动生成临时变量First.Region、Last.Region、First.Subsidiary 和Last.Subsidiary。其中First.Region、Last.Region在本例中未用到。
因为需要计算各附属品牌的总销售额,所以每次出现新品牌(First.Subsidiary为1)时将累加变量,并将Total_Sales_Subsidiary置为0。
求和语句将对Sales值进行累加,结果存储在Total_Sales_Subsidiary中。
当Subsidary的值为该分组内最后一个值(Last.Subsidiary为1)时,才将当前输出PDV中的观测输出,此时Total_Sales_Subsidiary为该品牌的总销售额。当前输出PDV中的变量为Region、Subsidiary、Sales和Total_Sales_Subsidiary。
由于输出观测中的变量Sales为每个分组内最后一个产品的销售额,没有意义,因此在DATA语句中使用数据集选项DROP=指明不将变量Sales写入输出数据集work.shoes_subsidiary。
此外,FORMAT语句在编译时指定累加变量Total_Sales_Subsidiary的输出格式为DOLLAR10.。
所生成的work.shoes_subsidiary在VIEWTABLE窗口中打开如图3.26所示。
image

3.?使用RETAIN语句保持变量值
默认情况下,DATA步中所有变量在每次迭代开始前都会被设置为缺失值。而RETAIN语句中指定的变量则不会,其值会一直保持着,在下次迭代中仍然可以使用。RETAIN语句的基本形式如下:
RETAIN 元素列表1 <初始值1 | 初始值列表1> <...元素列表n <初始n | 初始值列表n> >;
其中:
元素列表指定要在历次迭代中保持其值的变量名、变量列表或数组名。
初始值或初始值列表为其前面的元素指定的初值(为数字或字符)。当指定一个初始值时,该初始值被指定为其前面元素列表中的所有元素的初值。若指定的是初始值列表(多个初始值),SAS会将该列表中的第一个值指定给第一个元素,第二个值指定给第二个元素,依此类推。当未指定初始值或初始值列表时,其前面的元素的初始值为缺失值。
例3.22:基于数据集saslib.sales,使用RETAIN语句和赋值语句计算公司产品全年总销售额。
示例代码如下:

data work.sales_retain;
    set saslib.sales;
    retain Total_Sales 0;
    Total_Sales=Total_Sales+Sales;
    format Total_Sales DOLLAR10.;
run;

proc print data=work.sales_retain noobs;
run;

RETAIN语句将Total_Sales的初值设置为0,并告诉SAS在每次迭代中保持Total_Sales的值。接下来的赋值语句将上次迭代中计算得到的Total_Sales值与当前观测中Sales的值相加,结果存储在Total_Sales中。PRINT语句打印输出数据集的内容如图3.27所示。
该例使用的数据saslib.sales中变量Sales没有缺失值。如果Sales中存在缺失值,那么赋值语句中表达式(Total_Sales+Sales)的结果也为缺失值,这样会导致当前及其后所有迭代中Total_Sales的值都为缺失值。读者可在SET语句中使用例3.20中使用的带缺失值的数据集saslib.sales2,并查看其生成数据集的内容。当数据值中包含缺失值时,还可以使用SUM函数对变量求和,该函数只会计算非缺失值的和,具体的接下来会介绍。
此外,使用RETAIN语句还需要注意的是,如果该变量名仅在RETAIN语句中出现,并且RETAIN语句中未对其赋初值,则该变量不会写入输出数据集中。反之,如果RETAIN语句中给出了变量初始值,即使该变量仅在RETAIN语句中出现,该变量也会写入输出数据集。
4.?使用SUM函数
SUM函数返回非缺失值参数的和。SUM函数的基本形式如下:
SUM(参数, 参数...);
该求和语句等效于RETAIN语句和SUM函数的组合。其中,参数指定为数字常量、数字变量或数字表达式。如果参数中包含缺失值,且所有参数都是缺失值,则返回缺失值;若任一参数不是缺失值,则返回非缺失值参数的总和。与求和语句不同,SUM函数不会保持任何变量的值,所以如果要想保持的变量,应该使用RETAIN语句。
例3.23:基于数据集saslib.sales,计算公司产品全年总销售额。
示例代码如下:

data work.sales_sumfunc;
    set saslib.sales;
    retain Total_Sales 0;
    Total_Sales=sum(Total_Sales,Sales);
    format Total_Sales DOLLAR10.;
run;

所生成的数据集work.sales_sumfunc 的数据和例3.22一样。

相关文章
|
9天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
76 9
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
AI技术深度解析:从基础到应用的全面介绍
人工智能(AI)技术的迅猛发展,正在深刻改变着我们的生活和工作方式。从自然语言处理(NLP)到机器学习,从神经网络到大型语言模型(LLM),AI技术的每一次进步都带来了前所未有的机遇和挑战。本文将从背景、历史、业务场景、Python代码示例、流程图以及如何上手等多个方面,对AI技术中的关键组件进行深度解析,为读者呈现一个全面而深入的AI技术世界。
67 10
|
23天前
|
机器学习/深度学习 人工智能 PyTorch
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
本文探讨了Transformer模型中变长输入序列的优化策略,旨在解决深度学习中常见的计算效率问题。文章首先介绍了批处理变长输入的技术挑战,特别是填充方法导致的资源浪费。随后,提出了多种优化技术,包括动态填充、PyTorch NestedTensors、FlashAttention2和XFormers的memory_efficient_attention。这些技术通过减少冗余计算、优化内存管理和改进计算模式,显著提升了模型的性能。实验结果显示,使用FlashAttention2和无填充策略的组合可以将步骤时间减少至323毫秒,相比未优化版本提升了约2.5倍。
42 3
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
|
20天前
|
前端开发 UED
React 文本区域组件 Textarea:深入解析与优化
本文介绍了 React 中 Textarea 组件的基础用法、常见问题及优化方法,包括状态绑定、初始值设置、样式自定义、性能优化和跨浏览器兼容性处理,并提供了代码案例。
48 8
|
26天前
|
测试技术 开发者 Python
使用Python解析和分析源代码
本文介绍了如何使用Python的`ast`模块解析和分析Python源代码,包括安装准备、解析源代码、分析抽象语法树(AST)等步骤,展示了通过自定义`NodeVisitor`类遍历AST并提取信息的方法,为代码质量提升和自动化工具开发提供基础。
43 8
|
21天前
|
机器学习/深度学习 搜索推荐 API
淘宝/天猫按图搜索(拍立淘)API的深度解析与应用实践
在数字化时代,电商行业迅速发展,个性化、便捷性和高效性成为消费者新需求。淘宝/天猫推出的拍立淘API,利用图像识别技术,提供精准的购物搜索体验。本文深入探讨其原理、优势、应用场景及实现方法,助力电商技术和用户体验提升。
|
26天前
|
缓存 NoSQL Java
千万级电商线上无阻塞双buffer缓冲优化ID生成机制深度解析
【11月更文挑战第30天】在千万级电商系统中,ID生成机制是核心基础设施之一。一个高效、可靠的ID生成系统对于保障系统的稳定性和性能至关重要。本文将深入探讨一种在千万级电商线上广泛应用的ID生成机制——无阻塞双buffer缓冲优化方案。本文从概述、功能点、背景、业务点、底层原理等多个维度进行解析,并通过Java语言实现多个示例,指出各自实践的优缺点。希望给需要的同学提供一些参考。
45 7
|
24天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
44 4
|
23天前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
27天前
|
缓存 并行计算 Linux
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
30 2

热门文章

最新文章

推荐镜像

更多