1

いくつかのレコードが互いに関連している 2 つのデータ セットがあります。

例えば

データセット1

Var1

abcde

悪人

ビッグ・バン

毎日

まさに

データセット2

var1

abc

cde

悪い

悪い男

知らない人

ここで、ループ ロジックを使用してこれらのレコードを比較したいと思います。これが私のコードです。

%let id1=%sysfunc(open(dataset2,in)); %let colterm=%sysfunc(varnum(&id1,var1)); %do %while(%sysfunc(fetch(&id1)) eq 0); %let vterm=%sysfunc(getvarc(&id1,&colterm));

        data dataset1;
            set dataset1;
            if index(strip(var1),strip("&vterm"))>0 or index(strip("&vterm"),strip(var1))>0 then do;/*when one contains the other*/
            match="Fuzzy";
            cnt=cnt+1;
            end;
        run;
    %end;

    proc sql noprint;
      select max(cnt) into:maxnum/*to get max cnt*/
      from dataset1;
    quit;

今、dataset1 は以下のようになります

Var1 cnt 一致

abcde 2 ファジー

悪い男 2 ファジー

ビッグバン 0

奇妙な 1 ファジー

毎日 0

正確に 0

データセット 2 の関連するレコードをデータセット 1 にマージすると、新しいデータセット 1 は次のようになります。

Var1 cnt 一致 FM_dataset2_1 FM_dataset2_2

abcde 2 ファジー abc cde

悪い男 2 ファジー悪い悪い男 a

ビッグバン 0

奇妙な 1 あいまいな見知らぬ人

毎日 0

正確に 0

ご覧のとおり、新しい変数 FM_dataset2_ 1と FM_dataset2_ 2は、1 つのカウンター cnt に基づいて自動再割り当てされた変数です。しかし、SAS コードを使用してこのステップを実現する適切な方法を思いつきませんでした。

さらに、データセットを xml ファイルに出力する必要があります。結果は以下のようになります

<text>abcde</text>
<match>Fuzzy</match>
  <matchitem>abc</matchitem> 
  <matchitem>tecde</matchitem> 

問題は、上記の問題と同様に、matchitem 要素の数を決定してファイルに書き込む方法についてもです。xmlマップファイルでは、次のように位置を決定できます

     <COLUMN name="FM_dataset2_1">
            <PATH syntax="XPath">/../matchitem[position()=**1**]</PATH>
...

     <COLUMN name="FM_dataset2_2">
            <PATH syntax="XPath">/../matchitem[position()=**2**]</PATH>

ただし、これはケースバイケースで手動で行う必要があります。cnt カウンター (maxnum) に基づいてマップ ファイルを自動的にカスタマイズすることはできますか?

誰でも提案できますか?

4

1 に答える 1

1

以下よりも効率的なコードがあると確信していますが、私はあなたの考えにとどまろうとしました. 私は XML エンジンの操作に慣れていないので、その部分は他の人に任せます。それ以外の場合は、手動で作成する必要がある場合は、MAXNUM マクロ変数を作成する正しい軌道に乗っていたので、ループで使用できます。

%let id1=%sysfunc(open(dataset2,in));
%let colterm=%sysfunc(varnum(&id1,var1));
%do %while(%sysfunc(fetch(&id1)) eq 0);
%let vterm=%sysfunc(getvarc(&id1,&colterm));

   data dataset1;
      set dataset1;
      format vterm $20.;
      if match eq "Fuzzy" then output;
      if index(strip(var1),strip("&vterm"))>0 or index(strip("&vterm"),strip(var1))>0 then do;
         cnt=sum(cnt,1);
         match="Fuzzy";
         vterm = "&vterm";
         output;
      end;
      else do;
         cnt=sum(cnt,0);
         output;
      end;
   run;

   proc sort data=dataset1;
      by var1 match vterm descending cnt;
   proc sort data=dataset1 nodupkey;
      by var1 match vterm;
   run;
%end;

proc sql;
   create table maxcnt as
      select
         var1,
         match,
         max(cnt) as cnt
      from dataset1
      group by 1,2
      ;
   quit;
run;

proc transpose data=dataset1 out=dataset1(drop=FM_dataset2_0 _name_) prefix=FM_dataset2_;
   by var1 match;
   id cnt;
   var vterm;
run;

data dataset1;
   merge dataset1 maxcnt;
   by var1 match;
run;

%let id2=%sysfunc(close(&id1));    /*closes out dataset2 in case you need it later */
于 2011-05-12T23:13:02.347 に答える