SAS / PROC FREQ TABLES - 如果频率小于给定值,我可以抑制频率和百分比吗?
SAS / PROC FREQ TABLES - can I suppress frequencies and percents if frequency is less than a given value?
我在 SAS 中使用 tagsets.excelxp 将数十个双向 table 输出到 .xml 文件。如果该行中的频率小于 10,是否有语法会抑制该行(频率和百分比)?我需要应用它来对结果进行去标识化处理,如果我可以自动化该过程而不是在每个输出的 table 中使用条件格式,那将是理想的。下面是我用来创建 tables.
的语法
ETA:我需要将这些抑制值包含在列频率和百分比的计算中,但我需要它们在最终 table 中不可见(我考虑过的选项示例:将整行,将字体变成白色,这样它就不会为这些单元格显示,用星号替换这些值)。
如有任何建议,我们将不胜感激!!!
谢谢!
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;
当我过去这样做时,我首先生成数据集的频率,然后过滤掉 N,然后重新打印数据集(通常使用制表)。
如果您不能从 freq 输出中完美地重新创建频率 table,您可以做一个简单的频率,检查哪些 ID 或变量或您要排除的内容,然后从输入数据集并重新运行整个频率。
我不相信您可以使用 PROC FREQ,但您可以使用 PROC TABULATE 轻松复制您的代码,并且您可以在那里使用自定义格式来屏蔽数字。此示例将其设置为 M 表示缺失,N 表示小于 5,其余值保留一位小数。您也可以将 M/N 替换为 space(单个 space)以不显示任何值。
*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 模板以使用上述自定义格式。不幸的是,我没有时间为你模拟这个,但也许其他人可以。我会把它留在这里以帮助您开始并稍后删除它。
D.Jay:Proc FREQ 不包含任何用于有条件地屏蔽其输出单元格的选项。您可以利用 ODS 系统的输出数据捕获功能和后续的 Proc REPORT 来生成所需的屏蔽输出。
我猜测 lss
和 grade_p
的角色是 技能水平 和 学生年级分别
生成一些示例数据
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 具有生成条件输出的强大功能。计算块用于 select 输出值或屏蔽值指示符。
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;
如果您必须为不同的数据集生成大量交叉列表,代码很容易被宏化。
我在 SAS 中使用 tagsets.excelxp 将数十个双向 table 输出到 .xml 文件。如果该行中的频率小于 10,是否有语法会抑制该行(频率和百分比)?我需要应用它来对结果进行去标识化处理,如果我可以自动化该过程而不是在每个输出的 table 中使用条件格式,那将是理想的。下面是我用来创建 tables.
的语法ETA:我需要将这些抑制值包含在列频率和百分比的计算中,但我需要它们在最终 table 中不可见(我考虑过的选项示例:将整行,将字体变成白色,这样它就不会为这些单元格显示,用星号替换这些值)。
如有任何建议,我们将不胜感激!!!
谢谢!
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;
当我过去这样做时,我首先生成数据集的频率,然后过滤掉 N,然后重新打印数据集(通常使用制表)。
如果您不能从 freq 输出中完美地重新创建频率 table,您可以做一个简单的频率,检查哪些 ID 或变量或您要排除的内容,然后从输入数据集并重新运行整个频率。
我不相信您可以使用 PROC FREQ,但您可以使用 PROC TABULATE 轻松复制您的代码,并且您可以在那里使用自定义格式来屏蔽数字。此示例将其设置为 M 表示缺失,N 表示小于 5,其余值保留一位小数。您也可以将 M/N 替换为 space(单个 space)以不显示任何值。
*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 模板以使用上述自定义格式。不幸的是,我没有时间为你模拟这个,但也许其他人可以。我会把它留在这里以帮助您开始并稍后删除它。
D.Jay:Proc FREQ 不包含任何用于有条件地屏蔽其输出单元格的选项。您可以利用 ODS 系统的输出数据捕获功能和后续的 Proc REPORT 来生成所需的屏蔽输出。
我猜测 lss
和 grade_p
的角色是 技能水平 和 学生年级分别
生成一些示例数据
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 具有生成条件输出的强大功能。计算块用于 select 输出值或屏蔽值指示符。
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;
如果您必须为不同的数据集生成大量交叉列表,代码很容易被宏化。