我正在寻找一种在SAS中创建垂直表的方法,其中每个变量都被视为行(而不是每行都是一个观察点)。
例如,假设我有一些公司的数据,其中一些比其他公司更重要。很容易使proc报告吐出一个包含一些变量的汇总表:
Name Price Shares MarketCap
co1 $5 100 $500
co2 $1 100 $100
co3 $2 200 $400
在此之后我想要做的是打印每个公司的详细信息页面,这个页面基本上是一个表格,其中包含描述列和值的列(可能是计算的第三列)。
Company 1
Location: CA
CEO: Bob Johnson
Industry: Semiconductors
Shares: 100
Share Price: $5
Market Cap: $500
我能想到在SAS中这样做的唯一方法是基本上转置所有内容,创建一个具有标签(Location,Stock Price,Etc)的新字符变量和一个具有该值的第二个字符变量然后make BY公司的两栏报告,为每个报告获取一个页面。这很麻烦,因为有些值是数字而其他值是字符,所以要让它们显示在一列上,需要创建一个新的字符变量并用数字变量的文本版本填充它。
我认为必须有一种更简单的方法来创建垂直表,因为有很多简单的方法来创建水平表。
答案 0 :(得分:1)
也许我错过了什么,但你没有回答自己的问题吗?它应该像以下一样简单:
创建一些示例数据。确保每列都应用了格式和标签:
data mydata;
attrib name length=$10 format=$10. label='FirstName'
blah length=6 format=comma6. label='SomeValue';
bygroup = 1; name = "Rob" ; blah = 1000; output;
bygroup = 2; name = "Pete"; blah = 100 ; output;
run;
转置数据以使其变高:
proc transpose data=mydata out=trans;
by bygroup;
var _all_;
run;
打印出来:
data _null_;
set trans2;
by bygroup;
if first.bygroup then do;
put bygroup;
put "------";
end;
put _label_ ":" value;
run;
结果:
1
------
FirstName :Rob
SomeValue :1,000
2
------
FirstName :P
SomeValue :100
答案 1 :(得分:1)
此解决方案可能更适合您的需求。
首先创建一个将用作模板的HTML文件。无论您想要放置值,都可以使用宏变量作为占位符,如下所示:
<html>
<h1> My title is &title </h1><br>
Name: &name <br>
Value of Blah: &blah
</html>
让它看起来很有吸引力。
接下来创建一个将导入HTML模板的宏,用实际值替换占位符并将结果保存到新文件中:
/*****************************************************************************
** PROGRAM: MACRO.RESOLVE_FILE.SAS
**
** READS IN A FILE AND REPLACES ANY MACRO REFERENCES IN THE FILE WITH THE
** ACTUAL MACRO VALUES. EG. IF THE FILE WAS AN HTML FILE AND IT CONTAINED
** THE FOLLOWING HTML:
**
** <TITLE>&HTML_TITLE</TITLE>
**
** THEN THE PROGRAM WOULD READ THE FILE IN AND RESOLVE IT SO THAT THE OUTPUT
** LOOKED LIKE THIS:
**
** <TITLE>ROB</TITLE>
**
** ... WHEN THE MACRO VARIABLE "HTML_TITLE" EXISTED AND CONTAINED A VALUE OF
** "ROB". THIS IS USEFUL WHEN YOU NEED TO CREATE "DYNAMIC" HTML FILES FROM
** SAS BUT DONT WANT TO DO IT FROM A DATASTEP USING PUT STATEMENTS. DOING
** IT THIS WAY IS MUCH CLEANER.
**
** PARAMETERS: NONE
**
******************************************************************************
** HISTORY:
** 1.0 MODIFIED: 22-JUL-2010 BY:RP
** - CREATED.
** 1.1 MODIFIED: 18-FEB-2011 BY:RP
** - ADDED LRECL OF 32K TO STOP TRUNCATION
*****************************************************************************/
%macro resolve_file(iFileIn=, iFileOut=);
data _null_;
length line $32767;
infile "&iFileIn" truncover lrecl=32767;
file "&iFileOut" lrecl=32767;
input;
line = resolve(_infile_);
len = length(line);
put line $varying. len;
run;
%mend;
创建一些测试数据。还要创建一些命令来调用上面的宏并传入数据集中的值:
data mydata;
attrib name length=$10 format=$10. label='FirstName'
blah length=6 format=comma6. label='SomeValue'
cmd1 length=$1000
cmd2 length=$1000
;
title = 1;
name = "Rob" ;
blah = 1000;
cmd1 = cats('%let title=',title,';',
'%let name=',name,';',
'%let blah=',blah,';');
cmd2 = cats('%resolve_file(iFileIn=c:\template.html, iFileOut=c:\result',title,'.html);');
output;
title = 2;
name = "Pete";
blah = 100 ;
cmd1 = cats('%let title=',title,';',
'%let name=',name,';',
'%let blah=',blah,';');
cmd2 = cats('%resolve_file(iFileIn=c:\template.html, iFileOut=c:\result',title,'.html);');
output;
run;
使用call execute
运行我们在先前数据集中创建的cmd1和cmd2。我们必须一次只执行1行的调用执行,以便使用正确的宏变量,所以使用循环。首先使用您首选的技术计算数据集中的行数:
proc sql noprint;
select count(*) into :nobs from mydata;
quit;
然后迭代执行一次一个命令的数据集,并将每一行构建为一个新文件:
%macro publish;
%local tmp;
%do tmp = 1 %to &nobs;
data _null_;
set mydata(firstobs=&tmp obs=&tmp);
call execute (cmd1);
call execute (cmd2);
run;
%end;
%mend;
%publish;
这应该可以解决问题。
答案 2 :(得分:0)
然后在其中一个解决方案中如何...在Bases SAS中打开一个表来查看它。转到视图 - &gt;表单视图。这将它放在您请求的布局中。它可能看起来不像你想要的那样,但它是一个快速的选择。
另一种方法是自己编写。创建一个宏,它将数据集和您想要指定的任何其他内容作为参数显示,并使用ODS,put语句或您想要的任何其他技术显示它。
我不知道SAS中有任何其他内置方法来执行此操作。