SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 847|回复: 4
打印 上一主题 下一主题

请教关于数据集转换的问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2006-4-16 22:53:10 | 只看该作者

请教关于数据集转换的问题

各位高手
我现在面临这样一个问题,希望得到大家的指点和帮助,谢谢。

有一个数据集格式如下:
serial,item
001,A
001,B
001,C
002,B
002,C
003,D
003,E
004,A
004,D
...,...

我希望能先找出使用过2个Item以上(含2个)的serial,然后统计item两两使用的人数。
例如:
item1,item2,count
A,B,100
A,C,234
A,D,355
...,...

注意:A,D与D,A是一样的不需要重复统计(其他的两两搭配也是一样)。

请教高手这段代码该如何写?

PS,有点类似于关联规则,通过sas的em模块倒是可以做出来。但是希望可以通过sas/base来完成这个工作:)
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2006-4-17 16:39:46 | 只看该作者

re:

不知道我的理解对不对:如果经过serial的筛选之后,假如A出现3次,B出现2次,那么A,B就记为6次?
如果这样的话:
data tmp1;
length serial $3. item $2.;
input serial $ item $;
cards;
001 A
001 B
001 C
002 A
002 D
003 A
003 B
004 D
;
run;

proc sql;
create table tmp1_1 as
select *,count(*) as ct from tmp1 group by serial having ct>1;
quit;

proc sql;
create table tmp2 as
select item,count(*) as freq from tmp1_1 group by item;
quit;

proc sql;
create table rslt as
select a.item as item1,b.item as item2,a.freq*b.freq as freq from
tmp2 as a , tmp2 as b where a.item < b.item;
quit;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2006-4-20 14:32:27 | 只看该作者

回复

thisischenhan:
我不是太理解你说的意思。
我需要的就是同时使用A和B的人数(serial相同算同一个人)。

不知道除了用sql来做,sas的数据步能否实现这样的功能呢?
关键是先要把数据集转变为如下格式:

serial,item1,item2
001,A,B
001.A,C
001,B,C
...

然后对item1和item2 汇总即可。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2006-4-21 10:14:04 | 只看该作者

re

原来如此,理解错误。这样以上sql稍改即可。不过我还是觉得sql比较直观。
data步,我试试这样:

注:数组的定义视具体情况修改,另外如果item的类型非常多,可能就不太合适了。
data tmp1;
length serial $3. item $1.;
input serial $ item $;
cards;
001 A
001 B
001 C
002 A
002 D
003 A
003 B
004 D
;
run;

proc sort data=tmp1;by serial item;run;

proc transpose data=tmp1 out=tmp2(drop=_NAME_);
by serial;
var item;
run;

data tmp3;
set tmp2;
length item1-item6 $3.;
array arr1(3) col1-col3;
array arr2(2,3) item1-item6;
do i=1 to 3;
   do j=i+1 to 3;
      arr2(i,j)=trim(left(arr1(i)))||','||trim(left(arr1(j)));
   end;
end;
drop i j col1-col3;
run;

proc transpose data=tmp3 out=tmp4(drop=_NAME_);
by serial;
var item1-item6;
run;

data tmp4;
set  tmp4;
if col1='' or substr(col1,index(col1,',')+1)='' then delete;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2006-4-25 18:12:52 | 只看该作者

re+

data test;
input serial$ item$;
cards;
001 A
001 B
001 C
001 D
002 A
002 B
002 C
002 D
003 D
003 E
003 F
003 G
004 A
004 D
004 E
005 F
;
run;
data test2 (rename=(item=item2));
set test;run;
proc sql;
create table test3 as select test.*,test2.item2 from test,test2 where test.serial=test2.serial;quit;

data test4(keep=serial item3);
set test3;
if item>=item2 then delete;
item3=compress(item||item2);
run;
proc sort data=test4;by item3;run;

proc freq data=test4;
table item3/out=freq nopercent nocum;run;
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2025-6-9 21:49 , Processed in 0.068133 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表