Account_id <- c("00qwerf1”, “00uiowe3”, “11heooiue” , “11heooihe” ,
"00sdffrg3”, “03vthjygjj”, “11mpouhhu” , “1poihbusw”)
Postcode <- c(“EN8 7WD”, “EN7 9BB”, “EN6 8YQ”, “EN8 7TT”, “EN7 9BC”, “EN6
8YQ”, “EN8 7WD”, “EN7 7WB)
Age <- c(“30”, “35”, “40”, “50”, “60”, “32”, “34”, “45”)
DF <- data.frame(Account_id, Postcode, Age)
我想对SAS中的数据框进行聚类分析。我了解从技术上讲,SAS中不使用数据框,但是我只是出于说明目的使用了这种格式。 Account_id
和Postcode
都是字符变量,Age
是数字变量。
下面是我执行数据步骤后使用的代码;
Proc fastclus data=DF maxc-8 maxiter=10 seed=5 out=clus;
Run;
聚类分析不起作用,因为Account_id
和Postcode
是字符变量。有没有办法将这些变量更改为数字变量,或者有一种可以同时使用字符和数字变量的聚类方法?
答案 0 :(得分:0)
在进行聚类之前,需要定义一个可用于计算观察值之间距离的度量。默认情况下,proc fastclus
使用Euclidean metric。这就要求所有输入变量都是数字变量,并且如果将它们全部重新缩放以具有相同的均值和方差,则它们将发挥最佳作用,以便它们在聚类增长时都同样重要。
如果要为每个邮政编码执行单独的聚类分析,则可以在by
语句中使用邮政编码,但是如果要将邮政编码本身用作聚类变量,则需要将其转换为数字形式。用两个变量替换邮政编码质心的经度和纬度可能是个不错的选择。
对于您的帐户ID变量而言,什么是一个好的选择并不那么明显,因为这似乎并不能衡量任何事情。我会尝试掌握帐户创建日期或上次活动日期之类的其他信息,这些可以更明显的方式转换为数值。
答案 1 :(得分:0)
您可以确定每个变量的唯一值,然后为fastclus
分配原始值的序数作为数字表示形式。
示例代码
注意:FASTCLUS seed =选项是一个数据集说明符,而不是一个简单的数字(与随机数生成器一起使用)
* hacky tweak to place your R coded data values in a SAS data set;
data have;
array _Account_id(8) $20 _temporary_ ("00qwerf1", "00uiowe3", "11heooiue" , "11heooihe" ,
"00sdffrg3", "03vthjygjj", "11mpouhhu" , "1poihbusw");
array _postcode(8) $7 _temporary_ ("EN8 7WD", "EN7 9BB", "EN6 8YQ", "EN8 7TT", "EN7 9BC", "EN6
8YQ", "EN8 7WD", "EN7 7WB");
array _age (8) $3 _temporary_ ("30", "35", "40", "50", "60", "32", "34", "45");
do _n_ = 1 to dim (_account_id);
Account_id = _account_id(_n_);
Postcode = _postcode(_n_);
Age = _age(_n_);
output;
end;
run;
* get lists of distinct values for each variable;
proc means noprint data=have;
class _all_;
ways 1;
output out=have_freq;
run;
* compute ordinal of each variables original value;
data have_freq2;
set have_freq;
if not missing(Account_id) then unum_Account_id + 1;
if not missing(Postcode) then unum_Postcode + 1;
if not missing(Age) then unum_Age + 1;
run;
* merge back by original value to obtain ordinal values;
proc sql;
create table have_unumified as
select
Account_id, Postcode, Age
, (select unum_Account_id from have_freq2 where have_freq2.Account_id = have.Account_id) as unum_Account_id
, (select unum_Postcode from have_freq2 where have_freq2.Postcode = have.Postcode) as unum_Postcode
, (select unum_Age from have_freq2 where have_freq2.Age = have.Age) as unum_Age
from have
;
run;
* fastclus on the ordinal values (seed= not specified);
Proc fastclus data=have_unumified maxc=8 maxiter=10 out=clus_on_unum;
var unum_:;
Run;