1

我正在使用带有 proc boxplot 和 proc report 的 BY 语句来为 BY 变量的每个级别创建一个图和一个表。照原样,代码打印所有图,然后打印所有表格。我希望它打印绘图,然后打印 By 变量的每个级别的表格(因此输出将在绘图和表格之间交替)。有没有办法做到这一点?

这是我目前用于绘图和表格的代码-

proc boxplot data=study;
plot Lead_Time*Study_ID/ horizontal;
by Project_Name;
format Lead_Time dum.;
run;

proc report data=study nowd;
column ID Title Contact Status Message Audience Priority;
by Project_Name;
run;

谢谢你!!

4

3 回答 3

1

如果您要按价值运行一次 procs,那很容易。创建一个宏以仅运行一个实例,然后用于proc sql为每个实例创建一个调用。这是完全动态的,可以很容易地调整以允许其他选项,例如多个变量、级别等。

给定一个按值:

*Macro that runs it once;
%macro run_reports(project_name=);
  title "Report for &project_name.";
  proc boxplot data=study;
   plot Lead_Time*Study_ID/ horizontal;
   where Project_Name="&project_name.";
   format Lead_Time dum.;
  run;

  proc report data=study nowd;
   column ID Title Contact Status Message Audience Priority;
   where Project_Name="&project_name.";
  run;
%mend run_Reports;

*SQL pull to create a list of macro calls;
proc sql;
select distinct cats('%run_Reports(project_name=',project_name,')')
  into :runlist separated by ' '
  from study;
quit;

&runlist.;

打开options symbolgen;以查看运行列表的外观,或查看您的输出窗口(或 9.3+ 中的结果窗口)。当您在生产中运行它时,添加noprintproc sql以避免生成该表。

于 2014-08-07T21:18:23.357 回答
1

不幸的是,我不认为 ODS(输出交付系统)可以交错程序的输出。您将需要使用宏来遍历所有 by 变量并为每个变量调用 BOXPLOT 和 REPORT。

像这样的东西:

%macro myreport();
%let byvars = A B C D;
%let n=4;

%do i=1 %to &n;
   %let var = %scan(&byvars,&i);
   proc something data=have(where=(byvar="&var"));
   ...;
   run;

   proc report data=have(where=(byvar="&var"));
   ....
   run;
%end;
%mend;

%myreport();

显然,您需要更改它以满足您的需求。它的 Stackoverflow 上有很多例子。这是一个:在SAS中循环字符值

于 2014-08-07T18:44:20.617 回答
1

这原则上可以使用PROC DOCUMENTODS DOCUMENT输出类型。这本身并不容易,但它是可能的,并且比宏选项有一些优势,尽管我不确定是否足以推荐它的使用。然而,它仍然值得探索。

首先,这在很大程度上是由 Cynthia Zender 的优秀教程指导(包括,巧合的是,使用相同的数据集!),Have It Your Way: Rearrange and Replay Your Output with ODS DOCUMENT,在 2009 年 SAS 全球论坛上发表。她最初描述了一种执行此操作的 GUI 方法,但后来在代码中对其进行了解释,这对于这类事情显然更胜一筹。Kevin Smith 在 2012 年 SGF 的ODS DOCUMENT From Scratch中涵盖了类似的内容,尽管 Cynthia 的论文在这里更适用(因为她涵盖了确切的主题)。

首先,您需要生成所有结果。在这里订购并不重要。我生成了一个按国家/地区适当排序的 SASHELP.PRDSALE 样本。

proc sort data=sashelp.prdsale out=prdsale;
by country;
run;

然后,我们生成一些表;一个proc手段和一个sgplot。请注意标题用于#BYVAL1确保包含标题 - 否则我们会丢失 procs 上的有用标签!

title "#BYVAL1 Report";


ods _all_ close;
ods document name=work.mydoc(write);
proc means data=prdsale sum;
 by country;
 class quarter year;
 var predict;
run;

proc sgplot data=prdsale;
 by country;
 vbar quarter/response=predict group=year groupdisplay=cluster;
run;

ods document close;
ods preferences;

现在,我们有一些错误,但可用于您真正想要的。您可以使用 Cynthia 或 Kevin 论文中的技术详细研究这一点;现在,我将介绍您为此目的所需要的内容。

它现在是这样组织的,想象一个文件夹树:

\报告\意味着\国家\

我们需要的是:

\报告\国家\手段

这很容易做到。执行此操作的代码如下。显然,对于生产过程,这将是更好的自动化;给定输入数据集,生成此代码应该很简单。请注意,BYVAL 是按值递增的,因此 CANADA 是 1 和 4,GERMANY 是 2 和 5,USA 是 3 和 6。

proc document name=work.mydoc_new(write);
 make CANADA, GERMANY, USA;   *make the lower level folders;
 run;

 dir ^^;  *Go to the bottom level, think "cd .." in unix/windows;
 dir CANADA;  *go to Canada folder;
 dir;         *Notes to the Listing destination where we are, not that important;
 copy \work.mydoc\Means#1\ByGroup1#1\Summary#1 to ^;  *copy that folder from orig doc to here;
 copy \work.mydoc\SGPlot#1\ByGroup4#1\SGPlot#1 to ^; *^ being current directory, like '.' in unix/windows; 

*您也可以复制 \ByGroup1#1 和 \Bygroup4#1 而没有树的最后一层。这会产生稍微不同的结果(表格周围会包含更多的文字),所以无论哪个符合您的期望。

**这里德国和美国也一样。请注意,这是易于自动化的部分!目录^^; 目录德国;目录;复制 \work.mydoc\Means#1\ByGroup2#1\Summary#1 到 ^; 复制 \work.mydoc\SGPlot#1\ByGroup5#1\SGPlot#1 到 ^;

 dir ^^;
 dir USA;
 dir;
 copy \work.mydoc\Means#1\ByGroup3#1\Summary#1 to ^;
 copy \work.mydoc\SGPlot#1\ByGroup6#1\SGPlot#1 to ^;



run;
quit;  *this is one of those run group procedures, need a quit;

现在,您只需要以replay正确的方式将其取出。

proc document name=mydoc_new;
 replay;
 run;
quit;

塔达,你有你想要的。

于 2014-08-07T19:33:23.080 回答