Sas 有人喝咖啡吗?

Sas 有人喝咖啡吗?,sas,Sas,我在C#尝试过这个,但没有太大成功。所以我现在在SAS尝试。使用EG会话和我的SAS代码,我们处理SASHELP.CLASS中的学生列表。 这些人希望彼此了解,每月随机配对,一起去喝咖啡约会 规则: 每月生成一个随机咖啡日期列表; 我将每个月的配对存储到一个历史数据集中,并每月追加一次 一个人不能在6个月内与同一个人一起喝咖啡。因此,我们为历史目的保留了一个单独的数据集,其中包含3个变量: 最后日期,InviterID,InvitedID 我们根据历史列表检查每个配对,我们仅将最近6个月的数据加

我在C#尝试过这个,但没有太大成功。所以我现在在SAS尝试。使用EG会话和我的SAS代码,我们处理SASHELP.CLASS中的学生列表。 这些人希望彼此了解,每月随机配对,一起去喝咖啡约会

规则: 每月生成一个随机咖啡日期列表; 我将每个月的配对存储到一个历史数据集中,并每月追加一次

一个人不能在6个月内与同一个人一起喝咖啡。因此,我们为历史目的保留了一个单独的数据集,其中包含3个变量: 最后日期,InviterID,InvitedID

我们根据历史列表检查每个配对,我们仅将最近6个月的数据加载到临时数据集中进行检查

如果未找到最近的匹配对,则将新的匹配对添加到新的配对数据集中,并从原始参与者数据集中删除2个名称(行),直到该数据集中的行数少于2行。(一个人不能与另一个人配对)

不幸的是,此列表中有19人,因此在我们添加新参与者之前,其中一人将被排除在外。有人想加入我们的咖啡俱乐部吗?:-)

因此,我首先从数据集中派生和ID(n),并且只保留名称

Data Participants(Keep=ID Name);
FORMAT ID 8.;
set SASHelp.class;
ID=_n_;
run;
这19个人将是我在咖啡俱乐部的参与者

我或多或少遵循这样的思路:

data _null_;
randvar = ceil(rand('UNIFORM') * 100000);
call symput('RANDSEED', randvar);
run;

data CR.names2(keep=MEMID randid);
set CR.MasterNames;
randid = rand('UNIFORM');
run;

proc sort data=CR.names2 ; by randid; run;

data CR.pairs(keep=pairgrp MEMID);
 set CR.names2 nobs=num_peeps;
 pairgrp+1;
 if pairgrp > floor(num_peeps/2) then pairgrp=1;
run;

proc sort data=CR.pairs; by pairgrp;run;

proc transpose data=CR.pairs 
                    out=CR.pairs2  (drop=_NAME_);
    var memid;
    by pairgrp;

run;

Data CR.Pairs3;
set CR.pairs2;
rename COL1=InviterID COL2=InvitedID;
run;
但我被卡住了:-( 其余的我需要帮助请

以前有人成功地进行过这种随机配对吗?我在这里抓救命稻草。。。 非常感谢您的帮助。
Len

这是我的想法。这远远不够有效。尤其是当NOB变得越来越大时,因为涉及到笛卡尔积。在这种情况下,我还通过添加另一行来欺骗奇数

  • 准备数据并生成空结果表
  • 创建所有可能的配对(组合)的列表,不包括最近的配对
  • 随机排序并向下遍历列表,直到每个元素都被拾取一次
  • 追加到结果表
  • 这有一个缺点,因为可能有一些成员无法获得配对,因为所有可能的合作伙伴都已被选中。为了避免这种情况,我们可以迭代,直到获得最多的配对。 编辑:增加迭代。现在程序随机抽签,直到每个人都匹配或达到阈值

    这个问题可能应该用面向矩阵的语言来实现,比如IML或R

    data Participants(Keep=ID Name) ;
        set SASHelp.class nobs = num_peeps ;
        ID=_n_ ;
        output ; 
        if _n_ = 1 and mod(num_peeps,2) then do ; /* get even number of members: empty ID to pair with last participant*/
            name = 'empty' ; 
            id = 0 ; 
            output ; 
        end ;
    run ;
    
    data list_of_meetings ;
        length iteration InviterID InvitedID 8. ;
    run ;
    
    /****
        iter  = number of club meetings
        hist  = length of memory for pairings
        tries = number of iterations to pair everyone
    ****/
    %macro loop_coffee (iter=, hist=6, tries= 10) ;
    
        proc sql noprint ; 
           select max(0,max(iteration)) + 1 into :base 
               from list_of_meetings ;
        quit ;
    
    %do i = &base. %to &iter. ; /* loop through number of meetings */
    
        proc sort data = list_of_meetings (where=(iteration >= &i - &hist )) out = lookup nodupkey ; by InviterID InvitedID ; run ; /* get memory of pairings */
    
        proc sql ; /* list all acceptable pairs */
        create table all_pairs as
            select a.ID as InviterID, b.ID as InvitedID
                from Participants a
                    inner join Participants b
                        on a.ID lt b.ID
                    left join lookup c /* exclude the memory */
                        on a.ID eq c.InviterID and b.ID eq c.InvitedID
                where c.InviterID is NULL ;
        quit ;
    
        %let j = 0 ;
        %let all_pairs = 0 ;
        %do %until (&all_pairs | &j > &tries) ; /* iterate and random sort until all members are paired */
            %let j = %eval( &j + 1 ) ;
    
            data all_pairs;
                set all_pairs;
                randnum = ranuni(12345 + &i + &j);
            run;
    
            proc sort data = all_pairs ; by randnum ; run ; /* random sort */
    
            data out_pairs ; /* select the pairs: no. of IDs/2 */
              declare hash h() ;
              h.defineKey("ID") ;
              h.defineDone() ;
                do until ( eof1 ) ;
                    set Participants (keep= ID) end = eof1 ; 
                    rc = h.add () ; /* populate list of members */
                end ;
                do until ( eof2 ) ;
                    set all_pairs (keep= InviterID InvitedID) end = eof2 ;
                    rc1 = h.check (key:InviterID) ;
                    rc2 = h.check (key:InvitedID) ;
                    if rc1 = 0 and rc2 = 0 then do ; 
                        rc = h.remove (key:InviterID) ; /* delete member from list if paired */
                        rc = h.remove (key:InvitedID) ;
                        output ; 
                    end ;
                    if h.num_items = 0 then do ;
                        call symput('all_pairs', 1 ) ;
                        stop ;
                    end;
                end ;
                stop ;
                keep InviterID InvitedID ;
            run ;
    
        %end ;
    
        data list_of_meetings ;
            set list_of_meetings (where=(iteration ne .))
                Out_pairs (in=pairs) ;
            if pairs then iteration = &i. ;
        run ; 
    
    %end ;
    %mend ;
    %loop_coffee (iter=10,hist=6,tries=10) ;