代码之家  ›  专栏  ›  技术社区  ›  doctorjay

SAS/PROC FREQ表格-如果频率小于给定值,是否可以抑制频率和百分比?

  •  -1
  • doctorjay  · 技术社区  · 6 年前

    我正在使用标记集。SAS中的excelxp可将数十个双向表输出到。xml文件。如果行中的频率小于10,是否存在抑制行(频率和百分比)的语法?我需要应用这一点来取消识别结果,如果我可以自动化这个过程,而不是在每个输出的表中使用条件格式,那将是非常理想的。下面是我用来创建表的语法。

    ETA:我需要将这些被抑制的值包括在列频率和百分比的计算中,但我需要它们在最终的表格中不可见(我考虑过的选项示例:将整行变灰,将字体变白,以便这些单元格不显示,将这些值替换为星号)。

    如有任何建议,将不胜感激!!!

    谢谢

    j博士

    %include 'C:\Users\Me\Documents\excltags.tpl';
    
    ods tagsets.excelxp file = "C:\Users\Me\Documents\Participation_rdg_LSS_3-8.xml"
        style = MonoChromePrinter
        options(
        convert_percentages = 'yes'
        embedded_titles = 'yes'
        );
        title1 'Participation';
        title2 'LSS-Level';
        title3 'Grades 3-8';
        title4 'Reading';
        ods noproctitle;
    
    proc sort data = part_rdg_3to8;
        by flag_accomm flag_participation lss_nm;
    run;
    
    proc freq data = part_rdg_3to8;
        by flag_accomm flag_participation;
            tables lss_nm*grade_p / crosslist nopercent;
    run;
    
    ods tagsets.excelxp close;
    
    3 回复  |  直到 6 年前
        1
  •  0
  •   Richard    6 年前

    D、 杰伊:Proc-FREQ不包含任何有条件屏蔽其输出单元格的选项。您可以通过后续过程报告利用ODS系统的输出数据捕获能力来生成所需的屏蔽输出。

    我在猜测 lss grade_p 作为一个 熟练水平 和a 学生年级水平 分别地

    生成一些示例数据

    data have;
      do student_id = 1 to 10000;
        flag1 = ranuni(123) < 0.4;
        flag2 = ranuni(123) < 0.6;
        lss = byte(65+int(26*ranuni(123)));
        grade = int(6*ranuni(123));
    
        * at every third lss force data to have a low percent of grades < 3;
        if mod(rank(lss),3)=0 then
          do until (grade > 2 or _n_ < 0.15);
            grade = int(6*ranuni(123));
            _n_ = ranuni(123);
          end;
        else if mod(rank(lss),7)=0 then
          do until (grade < 3 or _n_ < 0.15);
            grade = int(6*ranuni(123));
            _n_ = ranuni(123);
          end;
    
        output;
      end;
    run;
    
    proc sort data=have;
      by flag1 flag2;
      *where lss in ('A' 'B') and flag1 and flag2; * remove comment to limit amount of output during 'learning the code' phase;
    run;
    

    执行Proc FREQ

    仅捕获与已生成的输出相对应的数据

    ods _all_ close;
    * ods trace on;
    /* trace will log the Output names
     * that a procedure creates, and thus can be captured
     */
    ods output CrossList=crosslist;
    
    proc freq data=have;
      by flag1 flag2;
      tables lss * grade / crosslist nopercent;
    run;
    
    ods output close;
    ods trace off;
    

    现在生成输出到您的目标ODS目标(可以是ExcelXP、html、pdf等)

    需要生成具有屏蔽值的等效参考输出。

    * regular output of FREQ, to be compare to masked output
    * of some information via REPORT;
    
    proc freq data=have;
      by flag1 flag2;
      tables lss * grade / crosslist nopercent;
    run;
    

    Proc REPORT具有生成条件输出的强大功能。计算块用于为输出选择值或屏蔽值指示器。

    options missing = ' ';
    
    proc format;
      value $lss_report ' '= 'A0'x'Total';
      value grade_report . = 'Total';
      value blankfrq .b = '*masked*' ._=' ' other=[best8.];
      value blankpct .b = '*masked*' ._=' ' other=[6.2];
    
    proc report data=CrossList;
      by flag1 flag2;
      columns
        ('Table of lss by grade'
        lss grade 
        Frequency RowPercent ColPercent
        FreqMask RowPMask ColPMask
        )
      ;
      define lss / order order=formatted format=$lss_report. missing;
      define grade / display format=grade_report.;
      define Frequency / display noprint;
      define RowPercent / display noprint;
      define ColPercent / display noprint;
      define FreqMask / computed format=blankfrq. 'Frequency' ;
      define RowPMask / computed format=blankpct. 'Row/Percent';
      define ColPMask / computed format=blankpct. 'Column/Percent';
    
      compute FreqMask;
        if 0 <= RowPercent < 10 
          then FreqMask = .b;
          else FreqMask = Frequency;
      endcomp;
      compute RowPMask;
        if 0 <= RowPercent < 10
          then RowPMask = .b;
          else RowPMask = RowPercent;
      endcomp;
      compute ColPMask;
        if 0 <= RowPercent < 10 
          then ColPMask = .b;
          else ColPMask = ColPercent;
      endcomp;
    run;
    
    ods html close;
    

    如果必须为不同的数据集生成大量交叉列表,那么代码很容易宏化。

    enter image description here

        2
  •  0
  •   Joe    6 年前

    当我过去这样做时,我首先为数据集生成频率,然后过滤掉N,然后重新打印数据集(通常使用表格)。

    如果不能从freq输出完美地重新创建频率表,可以执行简单的频率,检查哪些ID或变量或要排除哪些,然后从输入数据集中过滤掉它们,然后重新运行整个频率。

        3
  •  0
  •   Reeza    6 年前

    我不相信您可以使用PROC-FREQ,但您可以使用PROC-tablate轻松地复制代码,并且可以使用自定义格式来屏蔽数字。此示例将其设置为M表示缺失,将其设置为N表示小于5,并将其余值设置为小数点后一位。也可以用空格(单个空格)替换M/N,使其不显示任何值。

    *Create a format to mask values less than 5;
    proc format;
     value mask_fmt
    
    . = 'M' /*missing*/
     low - < 5='N' /*less than 5 */
     other = [8.1]; /*remaining values with one decimal place*/
    run;
    
    *sort data for demo;
    proc sort data=sashelp.cars out=cars;
     by origin;
    run;
    
    ods tagsets.excelxp file='/folders/myfolders/demo.xml';
    
    
    *values partially masked;
    proc tabulate data=cars;
     where origin='Asia';
     by origin;
     class make cylinders;
     table make, cylinders*n*f=mask_fmt. ;
    run;
    
    ods tagsets.excelxp close; 
    

    这在SAS UE上进行了测试。

    编辑:忘记了百分比,所以这可能不适用,主要是因为我认为您不会得到与PROC FREQ(外观)中相同的百分比,所以这取决于它对您的重要性。实现这一点的另一种可能性是修改PROC FREQ模板以使用上述自定义格式。不幸的是,我没有时间为你模拟这个,但也许其他人可以。我将把这个放在这里,以帮助您开始并在以后删除它。