2012-07-25 103 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