Sas Proc转置的未知错误

Sas Proc转置的未知错误,sas,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_Vari

尝试使用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
填写以下表格:

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个)。输入数据集上没有其他列,因此我不确定产生输出的原因。我已经有了一个使用宏来创建自己的代理转置过程的方法,但是任何关于为什么会遇到上述情况的信息都将不胜感激。

如果没有看到一个有效的示例,很难确切地说出关于proc transpose生成的额外变量的情况

但是,我可以看到,在转置后,有三个因素可能会导致文件大小增加:

  • 如果您有
    选项compress=noset、proc transpose创建未压缩的数据集。此外,如果某些字符变量的长度不同,则它们将全部转换为一个具有其中最长长度的变量,如果在输出数据集中禁用压缩,则会进一步增加文件大小

  • 我怀疑文件大小的某些增加可能来自proc transpose生成的自动
    \u NAME\u
    列,该列包含输入数据集中每个ID目标组合额外的~100*max\u var\u NAME\u长度字节

  • 如果您使用的是
    选项compress=BINARY(即默认情况下以这种方式压缩所有输出数据集),SAS压缩算法在转置后可能效率较低。这是因为SAS一次只压缩一条记录,而这种类型的压缩对于较短的记录效果要差得多。不幸的是,你对此无能为力

  • 下面是一个如何避免这两个潜在问题的示例

    /*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;
    

    如果看不到一个有效的例子,很难确切地说关于proc transpose生成的额外变量这里发生了什么

    但是,我可以看到,在转置后,有三个因素可能会导致文件大小增加:

  • 如果您有
    选项compress=noset、proc transpose创建未压缩的数据集。此外,如果某些字符变量的长度不同,则它们将全部转换为一个具有其中最长长度的变量,如果在输出数据集中禁用压缩,则会进一步增加文件大小

  • 我怀疑文件大小的某些增加可能来自proc transpose生成的自动
    \u NAME\u
    列,该列包含输入数据集中每个ID目标组合额外的~100*max\u var\u NAME\u长度字节

  • 如果您使用的是
    选项compress=BINARY(即默认情况下以这种方式压缩所有输出数据集),SAS压缩算法在转置后可能效率较低。这是因为SAS一次只压缩一条记录,而这种类型的压缩对于较短的记录效果要差得多。不幸的是,你对此无能为力

  • 下面是一个如何避免这两个潜在问题的示例

    /*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;
    

    除了压缩的建议(这在处理中等大小的数据集时几乎总是一个很好的建议!),我还将提出一个不使用
    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解决方案,那么您需要提供一个可复制的示例(即,提供一些具有类似变量扩展的数据)。

    除了压缩的建议之外(即使在处理中等大小的数据集时,压缩也几乎总是一个好的建议!),我将提出一个不使用
    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看到重复,它将创建那么多列。对于每一行,因为这是列的工作方式。它看起来像是空的,一个