2017-05-19 4 views
0

問題があります。私は、IDが時間の経過とともに変化するときに、別のテーブル用のクロスウォークを作成する必要があります。 idの変更にかかわらず、初年度のidが必要です。SAS:時間とともに変化する値からクロスウォークを作成する

data have; 
input ORIG_ID $ CHANGE_ID $ YEAR 
AAA BBB 1990 
BBB AAA 1991 
PPP ZZZ 1993 
ZZZ YYY 1994 
YYY ZZZ 1996 
TTT MMM 1990 
; 

**What I want :** 

/****OUTPUT****/ 

CHANGE_ID ORIG_ID 
BBB  AAA 
ZZZ  PPP 
YYY  PPP 
MMM  TTT 
/*My logic so far*/ 
proc sql; 
    create table temp as 
    select CHANGE_ID, ORIG_ID 
    case 
     when (CHANGE_ID<ORIG_ID) then cat(CHANGE_ID,ORIG_ID) 
     when (ORIG_ID<CHANGE_ID) then cat(ORIG_ID,CHANGE_ID) 
     end as key, year 
    from dat 
    order by key,year; 
quit; 

data final; 
    retain CHANGE_ID ORIG_ID 
    set temp; 
    by key; 
    if first.key; 
run; 
/*But this works for id changing for AAA to BBB, may be not*/ 

あなたがどんな混乱を持っている場合は、私に教えてください:ここで

+0

データサイエンスや統計の観点から、クロスウォークについて聞いたことはありません。 IDの値の変化を追跡するための監査証跡について話していますか? –

+0

hehe :)。このクロスウォークは、時間の経過とともにIDが変更される別のデータセットに必要です。元のIDに変更され、元のIDと最悪のIDが変更されることがあります。私たちはすべての変更IDを発生の最初のものに保ちたい。これはあなたに理にかなっていますか? – ammosperros

答えて

1

は、ハッシュオブジェクトのアプローチである - それは

  • あなたは全体の入力テーブル
  • を保持するのに十分なメモリを持っていることをあれば動作します
  • IDごとに1回の変更がある場合は、
  • IDごとに複数の変更がある場合は、何らかの変更方法があります。
  • data have; 
    input ORIG_ID $ CHANGE_ID $ YEAR; 
    cards; 
    AAA BBB 1990 
    BBB AAA 1991 
    PPP ZZZ 1993 
    ZZZ YYY 1994 
    YYY ZZZ 1996 
    TTT MMM 1990 
    ; 
    run; 
    
    proc sort data = have; 
    by CHANGE_ID descending YEAR; 
    run; 
    
    data v_have /view = v_have; 
        set have; 
        by CHANGE_ID; 
        if first.CHANGE_ID then GRP = 0; 
        GRP + 1;  
    run; 
    
    
    data want; 
        informat CHANGE_ID ORIG_ID; 
        set v_have; 
        /*Although we need the whole table in the hash, we only need to process each CHANGE_ID once*/ 
        by CHANGE_ID; 
        if first.CHANGE_ID; 
    
        /*Create a hash object to hold the table*/ 
        if _n_ = 1 then do; 
        dcl hash h(dataset:'v_have'); 
        rc = h.definekey('CHANGE_ID','GRP'); 
        rc = h.definedata('ORIG_ID','YEAR'); 
        rc = h.definedone(); 
        end; 
    
        /*Make a temp copy of the starting ID*/ 
        T_CHANGE_ID = CHANGE_ID; 
        PREV_YEAR = 2000; 
        rc=0; 
    
        /*Follow chains of IDs backwards through the table, making sure we only step backwards in time to avoid looping*/ 
        do while(rc = 0 and YEAR < PREV_YEAR); 
        PREV_YEAR = YEAR; 
        CHANGE_ID = ORIG_ID; 
        /*If there are multiple records per CHANGE_ID, take the most recent one that's younger than the current record*/ 
        do GRP = 1 by 1 while(rc=0 and YEAR >= PREV_YEAR); 
         rc = h.find(); 
        end; 
        end; 
    
        /*Output the last CHANGE_ID we got to plus the starting ID */ 
        ORIG_ID = CHANGE_ID; 
        CHANGE_ID = T_CHANGE_ID; 
    
        /*Ignore trivial rows resulting from cycles*/ 
        if CHANGE_ID ne ORIG_ID; 
        keep CHANGE_ID ORIG_ID; 
    run; 
    

    さて、もう少し複雑ですが、正常に動作し


。私はマルチデータハッシュオブジェクトを使ってこれをやっているかもしれませんが、最初のソートを排除することが可能だと思います。

+0

おかげさまで近づいていますが、上記の結果では希望の出力が得られませんでした。元のIDは常に最初の年に発生したIDでなければならないことを覚えておいてください。私の入力は英数字で、年は201201 201203〜999912のようになります。 – ammosperros

+0

アルゴリズムを変更して、一般的な日付で動作し、必要な出力を生成するようにしました。 – user667489

+0

ありがとうございます。あなたのファンとして私を数えてください。アルゴリズムがどのように魔法をやっているかを理解するには、まだ時間が必要です。 – ammosperros

関連する問題