如何计算 SAS 中组内字符串变量的模式?
How do I calculate the mode of a string variable within a group in SAS?
我可以使用 proc sql
中的子查询来计算众数,但这是最简单的方法吗?此代码通过依赖于 max
中的 max
函数来处理计算众数时可能出现的平局。
ods html file = "sas_output.html";
data raw_data;
input cust_id $
category $
amount;
datalines;
A red 72.83
A red 80.22
A blue 0.2
A blue 33.62
A blue 30.63
A green 89.04
B blue 10.29
B red 97.07
B red 68.71
B red 98.2
B red 1.79
C green 92.94
C green 0.96
C red 15.23
D red 49.94
D blue 75.82
E blue 20.97
E blue 78.49
F green 87.92
F green 32.29
;
run;
proc sql;
create table modes as
select cust_id, mean(amount) as mean_amount, category as mode_category
from (
select *, count(1) as count from raw_data group by cust_id, category
)
group by cust_id
having count=max(count)
order by cust_id;
quit;
data modes;
set modes;
by cust_id;
if first.cust_id then output;
run;
data final_data;
merge raw_data modes;
by cust_id;
run;
proc print data=final_data noobs;
title "final data";
run;
ods html close;
我试过这样使用proc means
proc means data=raw_data;
class cust_id;
var category;
output out=modes mode=mode_category;
run;
但我收到错误 "Variable category in list does not match type prescribed for this list",因为 proc means
不支持字符变量。
SQL 当然是一个很好的方法。这是一个带有双 DOW loop 的数据步骤解决方案。如果需要,您也可以在同一步骤中使用此方法计算平均值。
对数据进行排序以便按组使用。
proc sort data=raw_data;
by cust_id category;
run;
读取数据集一次,按 cust_id 计算类别的每次出现次数。变量 maxfreq
存储最高计数,变量 mode
保留最高计数的类别。因为数据是按类别变量排序的,所以这将 return 在决胜局的情况下按字母顺序排列的最高值。
第二个循环输出值以及第一个循环的模式。
data want(drop=freq maxfreq);
do until (last.cust_id);
set raw_data;
by cust_id category;
if first.category then freq=0;
freq+1;
maxfreq=max(freq,maxfreq);
if freq=maxfreq then mode=category;
end;
do until (last.cust_id);
set raw_data;
by cust_id;
output;
end;
run;
我可以使用 proc sql
中的子查询来计算众数,但这是最简单的方法吗?此代码通过依赖于 max
中的 max
函数来处理计算众数时可能出现的平局。
ods html file = "sas_output.html";
data raw_data;
input cust_id $
category $
amount;
datalines;
A red 72.83
A red 80.22
A blue 0.2
A blue 33.62
A blue 30.63
A green 89.04
B blue 10.29
B red 97.07
B red 68.71
B red 98.2
B red 1.79
C green 92.94
C green 0.96
C red 15.23
D red 49.94
D blue 75.82
E blue 20.97
E blue 78.49
F green 87.92
F green 32.29
;
run;
proc sql;
create table modes as
select cust_id, mean(amount) as mean_amount, category as mode_category
from (
select *, count(1) as count from raw_data group by cust_id, category
)
group by cust_id
having count=max(count)
order by cust_id;
quit;
data modes;
set modes;
by cust_id;
if first.cust_id then output;
run;
data final_data;
merge raw_data modes;
by cust_id;
run;
proc print data=final_data noobs;
title "final data";
run;
ods html close;
我试过这样使用proc means
proc means data=raw_data;
class cust_id;
var category;
output out=modes mode=mode_category;
run;
但我收到错误 "Variable category in list does not match type prescribed for this list",因为 proc means
不支持字符变量。
SQL 当然是一个很好的方法。这是一个带有双 DOW loop 的数据步骤解决方案。如果需要,您也可以在同一步骤中使用此方法计算平均值。
对数据进行排序以便按组使用。
proc sort data=raw_data;
by cust_id category;
run;
读取数据集一次,按 cust_id 计算类别的每次出现次数。变量 maxfreq
存储最高计数,变量 mode
保留最高计数的类别。因为数据是按类别变量排序的,所以这将 return 在决胜局的情况下按字母顺序排列的最高值。
第二个循环输出值以及第一个循环的模式。
data want(drop=freq maxfreq);
do until (last.cust_id);
set raw_data;
by cust_id category;
if first.category then freq=0;
freq+1;
maxfreq=max(freq,maxfreq);
if freq=maxfreq then mode=category;
end;
do until (last.cust_id);
set raw_data;
by cust_id;
output;
end;
run;