SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 3302|回复: 11
打印 上一主题 下一主题

请教一个SAS编程的题目

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2011-8-9 21:01:45 | 只看该作者

请教一个SAS编程的题目

向高手请教一段代码,谢谢。
需求如下:
1、原始数据集格式:
item_id,prop
1,A
1,B
1,C
1,D
1,E
1,F
2,A
2,C
2,G
2,H
3,C
3,D
3,J
...
2、需求:
需要计算item与item组合的prop重合度,例如item_id=1的prop是(A,B,C,D,E,F),item_id=2的prop是(A,C,G,H),重合的prop个数是2(即A、C重合).
计算后的结果如下:item组合后要求item2>item1,item1_count表示item1的prop个数,item2_count表示item2的prop个数,match_count表示item1和item2重合prop个数
item_1,item_2,item1_count,item2_count,match_count
1,2,6,4,2
1,3,6,3,2
2,3,4,3,1
...
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2011-8-10 00:09:52 | 只看该作者

Re: 请教一个SAS编程的题目

data raw;
format item_id prop $1.;
infile datalines dlm=',';
input item_id $ prop $ ;
cards;
1,A
1,B
1,C
1,D
1,E
1,F
2,A
2,C
2,G
2,H
3,C
3,D
3,J
;
run;

proc sql;
select count(distinct prop) into:nump from raw;
quit;

data temp1;
length allp $&nump..;
set raw;
by item_ID;
retain allp;
if first.item_ID then do;allp='';nump=0;end;
nump+1;
allp=strip(allp)||prop;
if last.item_id then output;
drop prop;
run;

   data result;
       set temp1 nobs=nobs;
        item1= item_id;
        item1_count=nump;
        lagp=allp;
        do p=_n_+1 to nobs;
        set temp1 point=p ;
               item2=item_id;
               Item2_count=nump;                          
               match_count=0;
               do i=1 to &nump;
                   if not missing(substr(allp,i,1)) then match_count+ index(lagp,substr(allp,i,1)) ne 0;                               
               end;
               output;
        end;
      keep item1: item2: mat:;
   run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2011-8-10 10:58:30 | 只看该作者

Re: 请教一个SAS编程的题目

谢谢sun
很好的思路,通过两个set + point=的应用把两张表连接起来了。
我现在担心的就是性能的问题:
1、do p=_n_+1 to nobs;--nobs可能是几百万
2、do i=1 to &nump; --&nump可能是几十万

这里面的循环量比较大,不知道是否还有更高性能的算法?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2011-8-10 12:12:46 | 只看该作者

Re: 请教一个SAS编程的题目

看看这样效率是否会高些....避免了内循环...
[code:2wu8g11e]data test;
infile cards dsd;
input item_id prop $;
cards;
1,A
1,B
1,C
1,D
1,E
1,F
2,A
2,C
2,G
2,H
3,C
3,D
3,J
;
data one(drop=prop);
  set test;
  by item_id notsorted;
  length id_prop $30;
  retain id_prop;
  if first.item_id then id_prop='';
  id_prop=trimn(id_prop)||prop;
  if last.item_id;
run;

data two(keep=item_1 item_2 item1_count item2_count match_count);
  set one nobs=obs;
  retain item_1;
  temp=lag(id_prop);
  item_1=lag(item_id);
  if _n_ ne 1 then do i=_n_ to obs;
    set one point=i;
        item_2=item_id;
        item1_count=length(temp);
        item2_count=length(id_prop);
        match_count=countc(strip(temp),strip(id_prop),'i');
        output;
  end;
run;[/code:2wu8g11e]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2011-8-10 14:09:41 | 只看该作者

Re: 请教一个SAS编程的题目

谢谢天性爱好者提供的思路。

补充一下:prop在真实数据中是一个字符串,不是A、B、C、D之类的单字符。
所以在生成prop连接的时候可以在中间用";"连接,如A;B;C...

match_count=countc(strip(temp),strip(id_prop),'i');
用countc函数来计算两个字符串的重合度好像有问题的。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2011-8-10 14:17:08 | 只看该作者

Re: 请教一个SAS编程的题目

是字符串的话,那就试着换成countw之类的函数试试...
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2011-8-10 14:42:01 | 只看该作者

Re: 请教一个SAS编程的题目

字符串的没有考虑到...貌似用那个不好行通,得自己编写个函数...   <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2011-8-11 05:42:35 | 只看该作者

Re: 请教一个SAS编程的题目

looks like a basket analysis or social circle analysis
depending on the number of item_id and unique PROP, efficiency consideration is different
cartesian join is a good tool and on SQL servers, it is actually pretty fast

[code:3hl4svsa]
data test(index=(item_id));
   input item_id prop $;
cards;
1 A
1 B
1 C
1 D
1 E
1 F
2 A
2 C
2 G
2 H
3 C
3 D
3 J
;
run;

proc sql;
     create table final as
         select a&#46;item_id as item_id1, b&#46;item_id as item_id2,
                count(distinct a&#46;prop) as item_count1,
                        count(distinct b&#46;prop) as item_count2,
                        sum(a&#46;prop=b&#46;prop) as match_count
         from test as a, test as b
         where  a&#46;item_id&lt;b&#46;item_id
         group by a&#46;item_id, b&#46;item_id
         ;
quit;

[/code:3hl4svsa]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2011-8-12 00:02:01 | 只看该作者

Re: 请教一个SAS编程的题目

[code:3f9jd6ql]data raw;
    infile datalines dlm=',';
    input item_id prop $;
datalines;
1,A
1,B
1,C
1,D
1,E
1,F
2,A
2,C
2,G
2,H
3,C
3,D
3,J
;
data raw;
    set raw;
    by item_id;
    if last&#46;item_id then group_flag=1;
run;
data out;
    length prop $8;
    declare hash h(hashexp&#58;4);
    rc=h&#46;defineKey('prop');
    rc=h&#46;defineData('prop');
    rc=h&#46;defineDone();
    do _n_=1 by 1 until(last&#46;item_id);
        set raw;
        by item_id;
        rc=h&#46;add();
    end;
    start+_n_;
    item_1=item_id; item1_count=_n_;
    do i=start+1 to last;
        set raw point=i nobs=last;
        item2_count+1;
        if h&#46;find()=0 then n+1;
        if group_flag then do;
            item_2=item_id;
            output;
            call missing(n,item2_count);
        end;
    end;
    rc=h&#46;delete();
    keep item_1 item_2 item1_count item2_count n;
run;[/code:3f9jd6ql]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2011-8-18 22:04:00 | 只看该作者

Re: 请教一个SAS编程的题目

能否解释一下如下部分代码,SAS是怎样做到连续读入数据到最后,而不是循环地读第一个Item_ID的?
谢谢!
  do _n_=1 by 1 until(last.item_id);
        set raw;
        by item_id;
        rc=h.add();
    end;
item1_count=_n_;
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 02:04 , Processed in 0.070499 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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