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 中执行此操作的唯一方法是基本上转置所有内容,创建一个具有标签(位置、股票价格等)的新字符变量和具有该值的第二个字符变量,然后创建一个两列按公司报告以获取每个页面。这很混乱,因为有些值是数字,而另一些是字符,因此要让它们显示在一列上,需要创建一个新的字符变量并用数字变量的文本版本填充它。

我认为必须有一种更简单的方法来创建垂直表,因为有很多简单的方法可以创建水平表。

4

3 回答 3

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;

这应该够了吧。

于 2012-07-27T18:13:52.313 回答
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
于 2012-07-25T21:37:08.663 回答
0

那么这些解决方案之一怎么样......在 Bases SAS 中打开一个表以查看它。转到视图-> 表单视图。这会将其置于您要求的布局中。它可能看起来不完全是您想要的方式,但它是一个快速的选择。

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

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

于 2012-07-27T15:10:49.413 回答