19、深入探索 SAS 中 REPORT 与 DOCUMENT 过程的高级应用

深入探索 SAS 中 REPORT 与 DOCUMENT 过程的高级应用

在 SAS 数据分析与报告生成的领域中, PROC REPORT 是一个强大的工具,它能帮助我们创建各种复杂的报告。同时, ODS DOCUMENT PROC DOCUMENT 则为报告的存储、管理和结构调整提供了更多的可能性。本文将详细介绍 RBREAK 语句的 CONTENTS= 选项,以及 ODS DOCUMENT PROC DOCUMENT 的使用方法和应用场景。

1. RBREAK 语句的 CONTENTS= 选项

RBREAK 语句的 CONTENTS= 选项仅在与 BEFORE 位置、 PAGE 选项和 SUMMARIZE 选项同时使用时才有效。使用该选项会在第三节点级别添加一个新条目。不过,由于该选项的使用条件较为严格,在大多数业务场景中可能不太实用。

以下是一个示例代码:

proc report data=orders;
    column customer_country product_line quantity total_retail_price;
    define customer_country / group;
    define product_line / group;
    rbreak before  / contents="Summary" page summarize;
run;

这个示例展示了如何使用 RBREAK 语句的 PAGE CONTENTS= 选项,运行后会添加一个标记为 “Summary” 的节点。

2. ODS DOCUMENT 和 PROC DOCUMENT 概述

通过 PROC REPORT 控制节点数量和标签可能会让人感到沮丧和困难。在某些情况下, PROC REPORT 对节点的控制能力有限。这时,我们可以先让 PROC REPORT 创建最少数量的必要节点,然后使用 ODS DOCUMENT 目的地和 PROC DOCUMENT 来重构目录结构并更改条目标签。

ODS DOCUMENT 目的地用于将输出对象存储在文档项存储中。我们可以从存储的信息中为多个 ODS 目的地生成输出,而无需重新运行原始的 PROC DATA 步骤。 PROC DOCUMENT 则更强大,它不仅可以将文档项存储中的输出对象发送到任何打开的 ODS 目的地(使用 REPLAY 语句),还可以更改输出对象的顺序和重构目录结构。

3. ODS DOCUMENT 约定

ODS DOCUMENT 目的地的语法与其他目的地相同,需要先打开目的地,在数据和过程步骤之后关闭目的地。

ods document name=temp;
proc report …
run;
ods document close;

ODS DOCUMENT 语句的默认访问模式是 Update ,它会将新的过程信息追加到已存在的文档项存储中。为了避免对存储内容的混淆,我们可以指定 Write 访问模式,该模式会删除存储中的所有现有内容,每次都从头开始。

需要注意的是,如果使用了自定义格式, ODS DOCUMENT 会存储临时格式,但不会保存永久格式。在重放文档时,需要确保 SAS 知道用户定义格式的位置,可以使用 PROC FORMAT 或带有 FMTSEARCH 选项的 OPTIONS 语句来实现。

4. PROC DOCUMENT 语句和选项

PROC DOCUMENT 有多个语句和选项,以下是一些常用的:
- LIST 语句 :用于列出文档中每个条目的内容。需要使用 LEVELS= DETAILS 选项, LEVELS=ALL 可以让输出包含存储中的每个条目和路径, DETAILS 选项则可以查看每个路径的 TYPE LABEL 变量值。
- MAKE 语句 :用于创建新目录,将对存储项的所有更改放在新目录中,避免对 PROC REPORT 创建的项造成意外更改。
- SETLABEL 语句 :用于分配节点标签。
- COPY 语句 :用于将 PROC REPORT 创建的项复制到新目录中,同样是为了避免意外更改。

PROC DOCUMENT 支持 RUN-Group 处理,因此 RUN 语句非常重要,它能确保所有语句都被执行。过程必须以 QUIT 语句结束,以正确终止。

5. 默认项分析

了解 PROC REPORT 放入文档项存储中的条目结构很重要。下面是一个简单的 PROC REPORT 步骤创建项存储的示例代码:

ods document name=temp(write);
proc report data=orders;
    column product_line quantity total_retail_price;
    define product_line / group;
run;
ods document close;
proc document name=temp;
    list / levels=all details;
run;
quit;

默认情况下, PROC REPORT 创建三个节点级别,文档存储通常有三个项:
| 序号 | 项类型 | 对应内容 | 标签默认值 |
| ---- | ---- | ---- | ---- |
| 1 | Dir | 由 ODS PROCLABEL 语句创建的过程标签,是包含输出对象的目录结构的顶部 | “The Report Procedure” |
| 2 | Dir | 对应 PROC REPORT 语句中 CONTENTS= 选项控制的报告标签,创建子目录 | “Detailed and/or summarized report” |
| 3 | 实际输出对象 | PROC REPORT 创建的表格 | 由于 ODS DOCUMENT 创建观察和 PROC REPORT 提供正确标签的时间顺序问题,标签值缺失 |

当在 BREAK 语句中添加 PAGE 选项时,虽然目录结构会发生变化,但文档存储中可能只包含一个表条目,这是由于时间问题导致的。例如:

ods document name=temp(write);
proc report data=orders;
    column customer_country product_line quantity total_retail_price;
    define customer_country / group;
    define product_line / group;
    break after customer_country / page;
run;
ods document close;
proc document name=temp;
    list / levels=all details;
run;
quit;

无论如何,文档存储至少会有两个项,一个是目录,另一个是表格输出对象。即使通过 PROC REPORT 移除目录中的第二和第三级节点,文档存储中仍然会有两个条目。

6. BY 变量项列表

当在 PROC REPORT 步骤中使用 BY 语句时,会为 BY 变量的每个唯一值在主目录下添加一个子目录,每个子目录都有一个唯一的序列号。多个 BY 变量不会改变子目录结构,但会增加子目录的数量,因为每个 BY 变量值的组合都会有一个对应的子目录。

以下是一个示例代码:

proc sort data=orders;
    by customer_age_group;
run;
ods document name=temp(write);
proc report data=orders;
    by customer_age_group;
    column product_line quantity total_retail_price;
    define product_line / group;
run;
ods document close;
proc document name=temp;
    list / levels=all details;
run;
quit;

假设 CUSTOMER_AGE_GROUP 变量有五个唯一值,那么会添加五个子目录,分别为 ByGroup1#1 ByGroup2#1 等。每个 BY 值目录下还有一个子目录,其中包含表格输出对象。

7. 创建具有多个子节点的父节点

在实际应用中,我们可能希望在目录中创建一个具有多个子节点的父节点。 BREAK 语句的 PAGE CONTENTS= 选项无法在项存储中创建多个项,因此无法直接用于创建子节点。而 PROC DOCUMENT 可以帮助我们实现这一需求。

创建一个具有多个子节点的父节点需要两个步骤:
1. 创建包含 PROC REPORT 输出的文档项存储 :需要使用 BY 语句来创建所需数量的项。

proc sort data=orders;
    by customer_country;
run;
ods document name=temp(write);
proc report data=orders contents="";
    by customer_country;
    format customer_country $cntry.;
    column customer_country product_line quantity total_retail_price;
    define customer_country / group;
    define product_line / group;
    break before customer_country / page contents="";
run;
ods document close;
  1. 在项存储中创建新目录并将输出对象移动到该目录 :为新目录和子节点设置有意义的标签。
proc document name=temp;
    make \parentchild;
    setlabel \parentchild "Country Sales";
    setlabel \Report#1\ByGroup1#1\Report#1 "Australia";
    copy \Report#1\ByGroup1#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup2#1\Report#1 "Canada";
    copy \Report#1\ByGroup2#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup3#1\Report#1 "Germany";
    copy \Report#1\ByGroup3#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup4#1\Report#1 "Israel";
    copy \Report#1\ByGroup4#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup5#1\Report#1 "Turkey";
    copy \Report#1\ByGroup5#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup6#1\Report#1 "United States";
    copy \Report#1\ByGroup6#1\Report#1 to \parentchild#1;
    setlabel \Report#1\ByGroup7#1\Report#1 "South Africa";
    copy \Report#1\ByGroup7#1\Report#1 to \parentchild#1;
run;
ods pdf file="CountrySales.pdf";
replay \parentchild;
run;
ods pdf close;
quit;

上述代码中,手动编写了所有的 SETLABEL COPY 语句,这可能会很繁琐且容易出错。我们可以使用宏程序来简化这个过程。使用宏程序更新项存储需要以下步骤:
1. 创建包含 PROC REPORT 输出的文档项存储。
2. 创建一个包含存储项列表的数据集。

ods output properties=itemlist;
proc document name=temp;
    list / levels=all details;
run;
quit;
  1. 为需要操作的每个路径和标签创建宏变量。
data _null_;
    set itemlist end=last;
    if _n_ ne 1 then do;
        if type not in ("Table") then do;
            countl+1;
            call symputx('label'||trim(left(countl)),scan(label,2,"="));
        end;
    end;
    if type in ("Table") then do;
        count+1;
        call symputx('path'||trim(left(count)),path);
    end;
    if last then call symputx('total',count);
run;
  1. 创建具有所需节点级别的新项结构,并将新结构重放到所需的 ODS 目的地。
%macro newtoc;
    proc document name=temp;
        make \parentchild;
        setlabel \parentchild "Country Sales";
        %do i=1 %to &total;
            setlabel &&path&i "&&label&i";
            copy &&path&i to \parentchild#1;
        %end;
    run;
    ods pdf file="CountrySales.pdf";
    replay \parentchild;
    run;
    ods pdf close;
    quit;
%mend newtoc;
%newtoc

通过以上步骤,我们可以更灵活地控制报告的目录结构,创建出满足需求的报告。希望本文对你在 SAS 中使用 PROC REPORT ODS DOCUMENT PROC DOCUMENT 有所帮助。

下面是创建具有多个子节点的父节点的流程图:

graph TD;
    A[创建包含PROC REPORT输出的文档项存储] --> B[创建包含存储项列表的数据集];
    B --> C[为路径和标签创建宏变量];
    C --> D[创建新项结构并重放];

通过上述内容,我们详细了解了 RBREAK 语句的 CONTENTS= 选项,以及 ODS DOCUMENT PROC DOCUMENT 的使用方法和应用场景。这些技术可以帮助我们更好地管理和定制 SAS 报告的结构和内容。在实际应用中,我们可以根据具体需求选择合适的方法,提高报告生成的效率和质量。

深入探索 SAS 中 REPORT 与 DOCUMENT 过程的高级应用

8. 宏程序实现的详细解释

在使用宏程序更新项存储以创建具有多个子节点的父节点时,每个步骤都有其特定的作用。

8.1 创建包含存储项列表的数据集
ods output properties=itemlist;
proc document name=temp;
    list / levels=all details;
run;
quit;
  • ods output properties=itemlist; :这行代码将 PROC DOCUMENT LIST 语句输出的信息存储到名为 itemlist 的数据集中。 LIST 语句结合 levels=all details 选项,会列出文档存储中所有条目的详细信息,包括路径、类型和标签等。
  • proc document name=temp; :指定要操作的文档存储为 temp
  • list / levels=all details; :列出 temp 文档存储中所有条目的详细信息。
  • run; quit; RUN 语句确保 PROC DOCUMENT 中的语句被执行, QUIT 语句正确终止该过程。
8.2 为路径和标签创建宏变量
data _null_;
    set itemlist end=last;
    if _n_ ne 1 then do;
        if type not in ("Table") then do;
            countl+1;
            call symputx('label'||trim(left(countl)),scan(label,2,"="));
        end;
    end;
    if type in ("Table") then do;
        count+1;
        call symputx('path'||trim(left(count)),path);
    end;
    if last then call symputx('total',count);
run;
  • data _null_; :这是一个空数据集,用于执行数据步操作而不创建实际的数据集。
  • set itemlist end=last; :从 itemlist 数据集中读取数据, end=last 用于标记最后一条记录。
  • if _n_ ne 1 then do; :跳过 itemlist 数据集中的第一条记录,因为第一条记录通常是主目录信息。
  • if type not in ("Table") then do; :处理非表格类型的条目,为每个 BY 变量项创建一个宏变量,其值为 BY 变量的值。
  • countl+1; :计数器,用于为每个 BY 变量项生成唯一的编号。
  • call symputx('label'||trim(left(countl)),scan(label,2,"=")); :创建宏变量,名称为 label1 label2 等,值为 BY 变量的值。
  • if type in ("Table") then do; :处理表格类型的条目,为每个表格项创建一个宏变量,其值为输出对象的路径。
  • count+1; :计数器,用于为每个表格项生成唯一的编号。
  • call symputx('path'||trim(left(count)),path); :创建宏变量,名称为 path1 path2 等,值为输出对象的路径。
  • if last then call symputx('total',count); :在处理完所有记录后,创建一个宏变量 total ,其值为输出对象的总数。
8.3 创建新项结构并重放
%macro newtoc;
    proc document name=temp;
        make \parentchild;
        setlabel \parentchild "Country Sales";
        %do i=1 %to &total;
            setlabel &&path&i "&&label&i";
            copy &&path&i to \parentchild#1;
        %end;
    run;
    ods pdf file="CountrySales.pdf";
    replay \parentchild;
    run;
    ods pdf close;
    quit;
%mend newtoc;
%newtoc
  • %macro newtoc; %mend newtoc; :定义一个名为 newtoc 的宏程序。
  • proc document name=temp; :指定要操作的文档存储为 temp
  • make \parentchild; :在文档存储中创建一个新的目录 \parentchild ,作为父节点。
  • setlabel \parentchild "Country Sales"; :为父节点设置标签为 “Country Sales”。
  • %do i=1 %to &total; :循环处理每个 BY 变量项。
  • setlabel &&path&i "&&label&i"; :为每个子节点设置标签,标签值为之前创建的 label 宏变量的值。
  • copy &&path&i to \parentchild#1; :将每个子节点的输出对象复制到新的父节点下。
  • ods pdf file="CountrySales.pdf"; :打开 ODS PDF 目的地,指定输出文件名为 “CountrySales.pdf”。
  • replay \parentchild; :重放新创建的目录 \parentchild ,将其内容输出到 ODS PDF 目的地。
  • run; quit; :确保 PROC DOCUMENT 中的语句被执行,并正确终止该过程。
9. 总结与实际应用建议

通过上述对 RBREAK 语句的 CONTENTS= 选项,以及 ODS DOCUMENT PROC DOCUMENT 的详细介绍,我们可以总结出以下要点:
- 功能总结
- RBREAK 语句的 CONTENTS= 选项在特定条件下可添加新节点,但使用场景有限。
- ODS DOCUMENT 用于存储输出对象, PROC DOCUMENT 用于管理和重构存储的内容,包括更改目录结构和节点标签。
- 使用 BY 语句可在文档存储中创建多个子目录,方便对数据进行分组管理。
- 通过宏程序可以简化创建具有多个子节点的父节点的过程,提高效率和减少错误。
- 实际应用建议
- 在使用 ODS DOCUMENT 时,根据实际需求选择合适的访问模式,避免数据混淆。
- 当需要对报告的目录结构进行复杂调整时,优先考虑使用 PROC DOCUMENT 和宏程序。
- 在处理自定义格式时,确保在重放文档时 SAS 能找到相应的格式。

以下是一个总结表格:
| 功能 | 描述 | 注意事项 |
| ---- | ---- | ---- |
| RBREAK 语句的 CONTENTS= 选项 | 在特定条件下添加新节点 | 与 BEFORE、PAGE 和 SUMMARIZE 选项同时使用 |
| ODS DOCUMENT | 存储输出对象 | 注意访问模式和自定义格式的处理 |
| PROC DOCUMENT | 管理和重构存储内容 | 支持 RUN - Group 处理,使用 RUN 和 QUIT 语句 |
| BY 语句 | 创建多个子目录 | 多个 BY 变量会增加子目录数量 |
| 宏程序 | 简化创建具有多个子节点的父节点的过程 | 需按步骤创建数据集和宏变量 |

10. 未来拓展方向

虽然本文介绍了 PROC REPORT ODS DOCUMENT PROC DOCUMENT 的常见应用场景,但在实际应用中还有很多可以拓展的方向。
- 自动化报告生成 :结合宏程序和数据驱动的方法,可以实现根据不同的数据集自动生成具有特定目录结构的报告。
- 与其他 SAS 过程结合 :可以将 PROC REPORT PROC SQL PROC FREQ 等其他 SAS 过程结合使用,获取更丰富的数据并生成更复杂的报告。
- 可视化报告 :将生成的报告与 SAS Visual Analytics 等工具结合,实现更直观的可视化展示。

通过不断探索和实践,我们可以充分发挥这些工具的潜力,为数据分析和报告生成提供更强大的支持。

希望以上内容能帮助你更好地理解和应用 SAS 中的这些高级功能,在实际工作中创造出更优质的报告。

提供了基于BP(Back Propagation)神经网络结合PID(比例-积分-微分)控制策略的Simulink仿真模型。该模型旨在实现对杨艺所著论文《基于S函数的BP神经网络PID控制器及Simulink仿真》中的理论进行实践验证。在Matlab 2016b环境下开发,经过测试,确保能够正常运行,适合学习和研究神经网络在控制系统中的应用。 特点 集成BP神经网络:模型中集成了BP神经网络用于提升PID控制器的性能,使之能更好地适应复杂控制环境。 PID控制优化:利用神经网络的自学习能力,对传统的PID控制算法进行了智能调整,提高控制精度和稳定性。 S函数应用:展示了如何在Simulink中通过S函数嵌入MATLAB代码,实现BP神经网络的定制化逻辑。 兼容性说明:虽然开发于Matlab 2016b,但理论上兼容后续版本,可能会需要调整少量配置以适配不同版本的Matlab。 使用指南 环境要求:确保你的电脑上安装有Matlab 2016b或更高版本。 模型加载: 下载本仓库到本地。 在Matlab中打开.slx文件。 运行仿真: 调整模型参数前,请先熟悉各模块功能和输入输出设置。 运行整个模型,观察控制效果。 参数调整: 用户可以自由调节神经网络的层数、节点数以及PID控制器的参数,探索不同的控制性能。 学习和修改: 通过阅读模型中的注释和查阅相关文献,加深对BP神经网络PID控制结合的理解。 如需修改S函数内的MATLAB代码,建议有一定的MATLAB编程基础。
基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文研究了一种基于遗传算法的新型异构分布式系统任务调度算法,并提供了Matlab代码实现。文章重点围绕异构环境中任务调度的优化问题,利用遗传算法进行求解,旨在提高资源利用率、降低任务完成时间并优化系统整体性能。文中详细阐述了算法的设计思路、编码方式、适应度函数构建、遗传操作流程及参数设置,并通过仿真实验验证了该算法相较于传统方法在调度效率和收敛性方面的优越性。此外,文档还列举了大量相关领域的研究案例和技术应用,涵盖电力系统、路径规划、车间调度、信号处理等多个方向,体现出较强的技术综合性实践价值。; 适合人群:具备一定编程基础和优化算法知识的研究生、科研人员及从事智能优化、分布式系统调度、电力系统、自动化等相关领域的工程技术人员。; 使用场景及目标:①解决异构分布式系统中的任务调度优化问题;②学习遗传算法在实际工程问题中的建模实现方法;③为科研项目提供算法参考代码复现支持;④拓展多领域交叉应用的研究思路。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注适应度函数设计遗传操作流程,并尝试在不同场景下调整参数以观察性能变化。同时可参考文中列出的相关研究方向进行延伸探索,提升综合应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值