Proc转置的未知错误

时间:2014-12-19 14:09:46

标签: sas

尝试将proc转置用于以下形式的数据集:

ID_Variable Target_Variable String_Variable_1 ... String_Variable_100
     1           0               The                   End
     2           0               Don't                 Stop

表格:

ID_Variable Target_Variable String_Variable
     1           0               The
     .           .               .
     .           .               .
     1           0               End
     2           0               Don't
     .           .               .
     .           .               .
     2           0               Stop

但是,当我运行代码时:

proc transpose data=input_data out=output_data;
    by ID_Variable Target_Variable;
    var String_Variable_1-String_Variable_100;
run;

文件大小从输入到输出的变化从33.6GB扩展到超过14TB,而不是上面描述的输出,我们的输出带有许多额外的完全空字符串变量(其中41个)。输入数据集上没有其他列,因此我不确定为什么会出现结果输出。我已经开始使用宏来创建我自己的代理转置过程,但是非常感谢有关上述情况的原因。

2 个答案:

答案 0 :(得分:3)

如果没有看到一个有效的例子,很难准确地说出proc转置生成的额外变量究竟发生了什么。

但是,在转置后,我可以看到三个可能有助于增加文件大小的内容:

  1. 如果设置了option compress = no;,proc转置会默认创建一个未压缩的数据集。此外,如果您的某些字符变量长度不同,则它们将全部转换为其中任何一个长度最长的变量,如果在输出数据集中禁用压缩,则会进一步增加文件大小。

  2. 我怀疑文件大小的某些增加可能来自proc transpose生成的自动_NAME_列,其中包含每个ID-target组合的额外~100 * max_var_name_length个字节。输入数据集。

  3. 如果您正在使用option compress = BINARY;(即默认压缩所有输出数据集),则SAS压缩算法在转置后可能效果较差。这是因为SAS一次只压缩一条记录,这种类型的压缩对于较短的记录效果要差得多。不幸的是,你无能为力。

  4. 以下是如何避免这两个潜在问题的示例。

    /*Start with a compressed dataset*/
    data have(compress = binary);
    length String_variable_1 $ 10 String_variable_2 $20; /*These are transposed into 1 var with length 20*/
    input ID_Variable Target_Variable String_Variable_1 $ String_Variable_2 $;
    cards;
         1           0               The                   End
         2           0               Don't                 Stop
    ;
    run;
    
    /*By default, proc transpose creates an uncompressed output dataset*/
    proc transpose data = have out = want_default prefix = string_variable;
        by ID_variable Target_variable;
        var String_Variable_1 String_Variable_2;
    run;
    
    /*Transposing with compression enabled and without the _NAME_ column*/
    proc transpose data = have out = want(drop = _NAME_ compress = binary) prefix = string_variable;
        by ID_variable Target_variable;
        var String_Variable_1 String_Variable_2;
    run;
    

答案 1 :(得分:3)

除了压缩的建议(在处理中等大小的数据集时几乎总是好的!),我会建议一个没有PROC TRANSPOSE的简单解决方案,并且有一些猜测的危险至于发生了什么。

首先,从宽到窄的转置通常在数据步骤中同样容易,有时可以更快(并非总是)。你不需要宏来做它,除非你真的喜欢输入符号和百分号,在这种情况下你可以随意。

data want;
  set have;
  array transvars string_Variable_1-string_Variable_100;
  do _t = 1 to dim(transvars);
    string_variable = transvars[_t];
    if not missing(String_variable) then output; *unless you want the missing ones;
  end;
  keep id_variable target_variable string_Variable;
run;

很好的短代码,如果你想要,你可以调用vname来获取转置变量的名称(或不是)。 PROC TRANSPOSE较短,但这足够短,以至于我经常只使用它。

其次,我的猜测。 41个额外的字符串变量告诉我,您BY组很可能会有一些重复项。如果PROC TRANSPOSE看到重复,它将创建许多列。对于每一行,因为这是列的工作方式。它看起来像是空的,谁知道,也许它们是空的 - 但如果它看到它们,SAS仍会转换空白的东西。

要验证这一点,请在转置前运行PROC SORT NODUPKEY。如果这不会删除至少40行(可能是空白行 - 如果这些数据来自excel或者我不会感到震惊,你知道最后有41行空白行)我会感到惊讶。如果它没有修复它,并且您不喜欢datastep解决方案,那么您需要提供一个可重现的示例(即,提供一些具有类似扩展变量的数据)。