2012-07-25 82 views
1

我正在寻找一种方法来在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的唯一方法是从根本上转了一切,创建具有标签(位置,股票价格等),并且具有第二字符变量一个新的字符变量价值,然后制作两列报告,由公司为每个报告获取一个页面。这是很麻烦的,因为有些值是数字的,而另外一些是字符的,所以为了让它们显示在一列上,需要创建一个新的字符变量并用数字变量的文本版本填充它。

我觉得有一个更简单的方法来创建一个垂直表,因为有很多简单的方法来创建水平表。

回答

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。我们必须一次只在一行上执行调用执行,以便使用正确的宏变量,因此可以使用循环。

proc sql noprint;  
    select count(*) into :nobs from mydata; 
quit; 

然后通过DataSet迭代同时执行的命令之一,并建立每行到一个新文件:使用您的首选技术首先计算数据集中的行数

%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; 

那应该做的伎俩。

+0

这真的很酷。我不知何故错过了这个答案(并通过导出数据解决了我的问题,然后使用一个Excel工作簿来生成表格),但我不得不再次做类似的事情,并且肯定会尝试这种方法。 – orh 2012-08-20 22:00:06

+0

谢谢 - 以防万一你最终使用它,我已经更新了'%resolve_file'宏,并修复了一些错误并增强了输出HTML的可读性(它现在保留了输出文件中的前导空格)。 – 2012-08-21 01:19:13

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 
+0

这个工作(并且可以用打印或报告而不是put语句来看起来不错),但我正在寻找一种更清洁的方法。基本上,我可以用proc打印一个好看的(假设我设置了一个样式)水平版本;按分组; var var1 var2 var3 var4;'我希望有办法强制proc print/report/tabulate制作这种垂直表。 – orh 2012-07-26 22:11:09

+0

我在下面添加了第三个答案,我认为更好地满足您的要求... – 2012-07-27 18:14:29

0

这些解决方案之一如何?取而代之的是...在Bases SAS中打开一个表格来查看它。转到查看 - >表单视图。这将它放入您要求的布局中。它可能看起来并不是你想要的,但它是一个快速的选择。

另一种方法是编写自己的。创建一个宏,它接受一个数据集和其他任何你想要指定的参数,并使用ODS,put语句或其他任何你想要的技术来显示它。

我不知道有任何其他内置SAS方法来做到这一点。

+0

是的,谢谢。我真的在寻找生产质量的产出。你的其他答案作为第一通道(所以我会接受它),但我不能得到超级有吸引力的输出。无限的时间,我可以推动ODS进行任何我想要的,但我真的希望在proc报告中会有一些漂亮的隐藏功能,可以快速翻转输出......哦。现在我只是将数据发送到csv并使用一揽子技巧来填充50个不同的excel表格。 – orh 2012-07-27 17:31:15