過去の桐井戸端BBS (桐ver.9)
22434 項目内データの重複を整理したい 平井 2003/09/21-10:30
6万ほどのデータベースがあります。
項目によって、「,」で区切ったデータが有り、
このなかに複数の重複したデータが入力されています。
これを整理し、単一化?したすっきりした項目データにしたいのですが、方法がわからず困っています。
条件選択と文字置換しか思いつかないのですが、重複データの種類が多く(多い場合6種ほど)計算式がとても長くなってしまいます。
良い方法が有れば、ご教授ください。お願いします。
22435 項目内データの重複とは 佐田 守弘 2003/09/21-12:41
記事番号22434へのコメント
平井さん
「項目内データの重複」との事ですが、これは具体的にどの様なデータの意味でしょうか。
文面から推察するに、以下の例の[備考]の様な形なのでしょうか。
=========================================================
[地名]    [備考]
東京   首都,メガロポリス,日本の首都,23区,首都,江戸
=========================================================
上記の通りだとすると、これは桐の基本的な機能の中で簡単に処置する方法がありません。

●原則論として
上記の様なデータは、元来、以下の様な形で持つべきです。
===========================
[地名]  [備考]
東京   首都
東京   メガロポリス
東京   日本の首都
東京   23区
東京   首都
東京   江戸
===========================
つまり元データを、カンマ位置で分けて、複数レコードの形に戻す処理が
まず最初に必要です。これには一括処理を使う必要があるでしょう。

●単一化の処理
上記の形になれば、単一化で重複行を削除することができます。

●つなぎ合わせ
そして元通りにつなぎ合わせたいのであれば、一括処理を使って、
カンマ区切り方式でのつなぎ合わせも可能です。

●問題は類義語処理
上記の例でいえば、「首都」と「メガロポリス」は類義語です。この類義語をどの様に扱うかが最大課題になるでしょう。
あるいは「首都」を「主都」と記述してある場合をどうするかも同じです。
この部分も整理する必要があるなら、まず最初に類義語辞書の表、
つまり、[原語]と[言換え語]のペアからなる表を作ります。そして元のデータの[原語]を[言換え語]に置換することによって、
用語の統一を行います。

佐田守弘(KS-00119)
22436 Re:項目内データの重複とは 佐田 守弘 2003/09/21-13:04
記事番号22435へのコメント
補足です
●再つなぎ合わせの処理
前掲の例でいえば、[地名]の「東京」が複数行で存在する場合に、
最後にまとめる際にそれらを全てつなぎ合わせてしまってよいのか、
それとも、元の状態を維持してつなぎ合わせるのかも判断のポイントになります。

元のデータの状態を維持したいのであれば、元の表で値が重複しない[ID]項目を作っておき、
バラした後に[ID]毎に[備考]をつなぎ合わせる必要があります。

●類義語処理の補足
類義語処理の中に入りますが、「似通った言い回し」をどの様に処理するかも課題になります。
別の例でいうと、
=====================================================================
[物件名] [内容]
桐村宅  3LDK,駅の近く,敷金1月,礼金なし
桐村宅  リビング和室4.5畳、和室6畳、洋間6畳、駅から徒歩1分,敷1礼0
=====================================================================
の様な例です。
「敷金1月,礼金なし」と「敷1礼0」は同じ意味ですが、書き方が違います。
「駅の近く」と「駅から徒歩1分」もほぼ同じ意味です。また、
「3LDK」よりも「リビング和室4.5畳、和室6畳、洋間6畳」は詳しい言い方です。
こういった処理も単一化するとなると、かなり中身が複雑になりそうです。

あるいは一方が誤りで、他方が正しい場合に、正しい方に合せて直す処理が
必要になるケースも予想されます。

結論的にいえば、具体的なデータを見れば、何らかの方法は必ず考えられると思いますが、
上記の例の様なケースも含めると、100%の処理は不可能な場合があり、
最終的には人間の目で確認して直す事が必要になるケースもあろうかと思います。

佐田守弘(KS-00119)

22437 Re:項目内データの重複とは 平井 2003/09/21-18:13
記事番号22435へのコメント
佐田 守弘さん

早々の回答ありがとうございます。質問をした平井です。

項目内データの重複は、佐田さんが例示されたものと同一です。
具体的には、データの分類項目(15種の用語)と検索のためのキーワード項目(100種程度の用語)の内容が重複しているのです。
したがって、佐田さんが回答されたように、通常の処理、たとえば置換程度の処理ではできないことわかりました。

さて、次に佐田さんが述べられた、
>元データを、カンマ位置で分けて、複数レコードの形に戻す処理が
>まず最初に必要です。これには一括処理を使う必要があるでしょう。

ですが、この一括のひな形など例示でご教授頂ければありがたいです。

>●単一化の処理
>上記の形になれば、単一化で重複行を削除することができます。

この処理は、できると思います。

>●つなぎ合わせ
>そして元通りにつなぎ合わせたいのであれば、一括処理を使って、カンマ区切り
>方式でのつなぎ合わせも可能です。

これもできれば、一括のひな形をご教授頂ければありがたいです。

>●問題は類義語処理

これは、用語の整理でして、私の場合は必要ないと思います。

以上、よろしきお願いします。


22455 Re:項目内データの重複とは 佐田 守弘 2003/09/22-23:16
記事番号22437へのコメント
平井さん
一括処理の雛型との事ですが、表の形や表の名称、項目名が分らない限り、
一括処理を作ることは不可能です。
そこで、前回私が書きました地名の例の表で雛型を書いてみます。

表名は以下の通りです。表の枠組みはいずれも同じです。
表A:元の表
表B:ワーク用に備考欄を分離した表
表C:備考欄のキーワードを単一化した表

なお、あくまでも雛型ですから、テストはできていません。
この様なプログラムの流れを参考にして、実際の表を対象として作って下さい。
単一化する部分もコマンドを書いてありますが、この部分は手作業で行った方が良いかと思います。
======================================================================
変数宣言 文字列{&地名,&備考全体,&備考部分}
変数宣言 整数{&P}
表 A
表 B
************************************
* 表Aの備考を分割して表Bに書き出す
************************************
編集表 A
繰り返し (.not #終端行)
 代入 &地名=[地名],&備考全体=[備考]
 繰り返し (.not &備考全体=#未定義)
  代入 &P=#文字位置(&備考全体,",")
  ケース開始
   ケース (&P>0)
    代入 &備考部分=#部分列(&備考全体,1,&P-1)
    代入 &備考全体=#部分列(&備考全体,&P+1)
   ケース (&P=0)
    代入 &備考部分=&備考全体
    代入 &備考全体=#未定義
  ケース終了
  編集表 B
  行追加 [地名]=&地名,[備考]=&備考部分
  編集表 A
 繰り返し終了
 ジャンプ 行番号=+1
繰り返し終了
終了 表 A

************************************
* 表Bを単一化する
************************************
編集表 B
絞り込み 単一化={[地名],[備考]}
絞り込み 補集合
行削除 *
解除 *
表整理 余白割合=10
ジャンプ 行番号=先頭

************************************
* 表Bの備考をつないで表Cに書き出す
************************************
表 C
編集表 B
繰り返し (.not #終端行)
 代入 &地名=[地名],&備考部分=[備考]
 条件 (&備考全体<>#未定義) 代入 &備考全体=&備考全体+","
 代入 &備考全体=&備考全体+&備考部分
 ジャンプ 行番号=+1
 ケース開始
  ケース (#終端行 .or &地名<>[地名])
   編集表 C
   行追加 [地名]=&地名,[備考]=&備考全体
   代入 &備考全体=#未定義
 ケース終了
繰り返し終了
終了 表 B
終了 表 C
終了
======================================================================
佐田守弘(KS-00119)
22457 Re:項目内データの重複を整理したいのですが。 うにん 2003/09/22-23:43
記事番号22434へのコメント
どこがいいかわからなかったのでとりあえず最初のにくっつけます。

平井さんは No.22434「項目内データの重複を整理したいのですが。」で書きました。
>6万ほどのデータベースがあります。項目によって、「,」で区切ったデータが有
>り、このなかに複数の重複したデータが入力されています。これを整理し、単一
>化?したすっきりした項目データにしたい

[項目]という項目の重複値を削除する一括処理を作ってみました。
ごく少ないデータでですが一応動作確認はしました。
データをレコードに分離する佐田さんの方式が本筋と思いますが、参考までに。

変数 整数{&i=0,&p},{&s}
絞り込み解除 *
置換 [項目]=","+#文字置換([項目],",",",,")+","
繰り返し
 &i=&i+2
 絞り込み [項目]{#COND(#対応文字列([],&i),[],[]="","A",1,"")}
 条件 (#EOF) 繰り返し中止
 置換 [項目]=#計算(#代入(&s,#対応文字列([],&i)),#代入(&p,#文字位置([],","+&s+",")),#部分列([],1,&p)+#文字置換(#部分列([],&p+1),","+&s+",",""))
繰り返し終了
絞り込み解除 *
置換 [項目]=#文字置換([],",,",",")
置換 [項目]=#部分列([項目],2,#文字数([項目])-2)

22459 Re:項目内データの重複とは KERO 2003/09/23-15:02
記事番号22437へのコメント
こんにちわ。横やりですいません。

現在のデータがカンマで区切られているのであれば、一括やイベントを使わなくてもできます。
(疲れます)
佐多さんのサンプルを引用させていただきますが、[地名][備考]の表の場合、
 #文字置換([備考],",",",") ←全角カンマを半角化(保険)
の後に全項目をCSV出力(このとき、項目名は出力しない設定が必要です。)して、
別の表に新規に読み込んではどうでしょうか?
別の表は新規作成で項目数2000(V8のMAX)の表を作って読み込みます。
結果として、[備考]にあるデータは横方向に項目として増加します。
その後、増加した項目を元の[備考]に別レコードとして戻します。

◆戻し方
新規作成した表の[1]に地名、[2]以降に元の[備考]データがカンマ位置で分割されて格納されます。
分割数はレコードによってまちまちです。
項目名[2000]の項目を出力作業用として使用します。
手順1
 [2]にデータがあるレコードを抽出します。
  [2]の項目で絞り込み→比較式→><#未定義で実行
   該当するレコードの[2]のデータを[2000]に複写します。
    [2000]の項目で置換→項目置換→計算式に[2]で実行
   該当するレコードがなければ処理終了です。
手順2
 [1]と[2000]を別表に書き出します。
  (ここで書き出し条件を設定します。「同名表が存在するとき」=追加の設定。書き出しする表名をWORK.TBLとします)
 絞込みを解除します。
手順3
 [3]にデータがあるレコードを抽出します。
  [3]の項目で絞り込み→比較式→><#未定義で実行
   該当するレコードの[3]のデータを[2000]に複写します。
    [2000]の項目で置換→項目置換→計算式に[3]で実行
   該当するレコードがなければ処理終了です。
手順4
 手順2で作った書き出し条件を実行します。
 WORK.TBLに[1]([地名])と[3]のデータが追加されます。

...お分かりでしょうが、これを繰り返すわけです。
 対象項目が[1999]になるか、手順2の絞込みで、条件を満たすレコードがなくなれば終わりです。

以上、便宜上、項目名の変更は省略しましたが、手作業での考え方です。いかがでしょうか?
定型作業でないのなら一括より手作業ですることが多いですよね?
このケースで、繰り返しする数が10回程度なら、手動でも苦にならないし(?)、履歴も実用に耐えます。
ただし、作業量からして、実際に[1999]まで手動では疲れますので一括でやると次のようになります。
*新規作成した表のみ開いている状態からの一括処理実行を前提として書きます。
========================================================================
  変数宣言 数値{&処理回数=2}
  変数宣言 文字列{&処理内容1,&処理内容2}
   繰り返し (&処理回数<2000)
    代入 &処理内容1="絞り込み [#文字列(&処理回数)+"]{><#未定義}"
    代入 &処理内容2="置換 [2000]=[#文字列(&処理回数)+"]
    コマンド &処理内容1
     条件 (&選択件数<1) 繰り返し中止
    コマンド &処理内容2
    書き出し 表,WORK.TBL,追加,{[1],[2000]}
    解除 *
    代入 &処理回数=&処理回数+1
   繰り返し終了
  表 "WORK.TBL"
  終了
========================================================================

>>●単一化の処理
>>上記の形になれば、単一化で重複行を削除することができます。

こちらも同様。
22460 Re:項目内データの重複とは KERO 2003/09/23-15:03
記事番号22459へのコメント
続きです。
>>●つなぎ合わせ
>これもできれば、一括のひな形をご教授頂ければありがたいです。

つなぎ合わせは、定型作業でしょうし、手作業が思いつきませんでした。
========================================================================
  変数宣言 数値{&処理回数=2,&確認}
  変数宣言 文字列{&地名,&キーワード}
   表 WORK.TBL
   表表示 [地名]
   代入 &確認=#ウィンドウハンドル取得(#IS表)
    ウィンドウ位置 最大化,&確認

   並べ替え {[地名]昇順} /*好きなソートがあれば次行を使います
*   並べ替え 条件名="なんとか" /*適当にソートしておいてください
   印字開始 "つなぎあわせた.CSV"
    印字 "地名,キーワード" /*項目名です
   ジャンプ 行番号=先頭
   繰り返し (.NOT #EOF)
    代入 &地名=[地名],&キーワード=","
     繰り返し (&地名=[地名])
      代入 &地名=&地名+","+[地名]
      ジャンプ 行番号=次行
     繰り返し終了
    印字 &地名,&キーワード
   繰り返し終了
   確認 "つなぎあわせた.CSV作成済みです"
   手続き終了
========================================================================
※テストしていません。ごめんなさい。
22461 Re:項目内データの重複を整理したいのですが。 平井 2003/09/23-21:57
記事番号22457へのコメント
質問した平井です。

うにんさん 回答ありがとうございます。うれしいです。
もう、回答はないのかなと心配していたと子です。

>[項目]という項目の重複値を削除する一括処理を作ってみました。
>ごく少ないデータでですが一応動作確認はしました。
>データをレコードに分離する佐田さんの方式が本筋と思いますが、参考までに。

ここに書いて頂いた、一括処理、是非試してみたいと思います。
後日、結果を報告したいと思います。
とりあえず、お礼まで。

P.S.一括処理は桐Ver5のDOSの時代、作成して使ったことがありますが、
ここ約10年ほどご無沙汰です。書かれている内容を理解するのが大変です。
22462 Re:項目内データの重複を整理したいのですが。 平井 2003/09/23-23:11
記事番号22457へのコメント
質問した平井です。

うにんさん、一括処理、大成功です。
約1〜2分の処理が完了しました。
手作業で行うと、何十時間もかかると思います。
ありがとうございました。

さて、一括処理での手順というか、どういう処理作業を行っているのか、
一括の内容がいまいち理解できていません。
できたら初心者向けに簡単な解説をいただけたらと思います。
お手数ですが、よろしくお願いします。

P.S.一時忘れていた桐、また好きになれそうです。

22463 Re:項目内データの重複とは 平井 2003/09/24-06:26
記事番号22455へのコメント
質問者の平井です。

佐田 守弘さん 一括処理の再回答ありがとうございます。

うにんさんの回答に目がつき、私の再質問に対する佐田さんの回答
があったのに気が付きませんでした。遅くなってすみません。

>一括処理の雛型との事ですが、表の形や表の名称、項目名が分らない限り、一括処理を
>作ることは不可能です。
>そこで、前回私が書きました地名の例の表で雛型を書いてみます。

この一括は、時間がなくまだ試しておりませんが、是非実行して、
その結果を報告したいと思います。

とりあえず、お礼まで。

P.S.うにんさんの一括とは、処理方法が違う?
22464 Re:項目内データの重複とは 平井 2003/09/24-06:32
記事番号22459へのコメント
質問者の平井です。

KEROさん 一括処理の雛形の回答ありがとうございます。

うにんさんの回答に目がつき、私の再質問に対するKEROさんの
一括処理の回答があったのに気が付きませんでした。遅くなってすみません。

>ただし、作業量からして、実際に[1999]まで手動では疲れますので一括でやると次のようになり
>ます。
>*新規作成した表のみ開いている状態からの一括処理実行を前提として書きます

この一括は、時間がなくまだ試しておりませんが、是非実行して、
その結果を報告したいと思います。

とりあえず、お礼まで。


22465 Re:項目内データの重複を整理したいのですが。 うにん 2003/09/24-09:50
記事番号22462へのコメント
>約1〜2分の処理が完了しました。

結構速かったですね。何度も置換するので心配でしたが。

>さて、一括処理での手順というか、どういう処理作業を行っているのか、
>一括の内容がいまいち理解できていません。

置換 [項目]=","+#文字置換([項目],",",",,")+","
データの間にカンマのある形式「a,b,c,b,c」
から両端にカンマのあるデータをつないだ

形式「,a,,b,,c,,b,,c,」に変換します。

 &i=&i+2
 絞り込み [項目]{#COND(#対応文字列([],&i),[],[]="","A",1,"")}
 条件 (#EOF) 繰り返し中止

その形式をカンマ区切りとみなして、偶数番目に文字列のある行を絞り込みます。
1行もなければ#EOFになるので終了します。
上の例では2,4,6,8,10番目に文字列があるので(最大で)5回目まで絞り込みの対象になります。

 置換 [項目]=#計算(#代入(&s,#対応文字列([],&i)),#代入(&p,#文字位置([],","+&s+",")),#部分列([],1,&p)+#文字置換(#部分列([],&p+1),","+&s+",",""))

偶数番目の文字列を重複検査用に&sに取り出し、
手前の","の位置を&pに取り出し、
その位置までの文字列(単一化処理済)と、その後ろの文字列から&s(と両端の",")を削除したものを連結した文字列に置換します。

上の例では、1回目の繰り返しでは「a」が取り出され、「,」と「a,,b,,c,,b,,c,」を連結した文字列
(重複していないので元のまま)で置換します。
2回目は「b」が取り出され、「,a,,」と、「b,,c,,b,,c,」から「,b,」
を取り除いた
「b,,c,,c,」を連結した文字列「,a,,b,,c,,c,」になります。
3回目は「c」が取り出され、以下2回目と同様。

最後に両端の","を
置換 [項目]=#部分列([項目],2,#文字数([項目])-2)
で削除し、データの間の2つずつになっている",,"を
置換 [項目]=#文字置換([],",,",",")
で1つにして完了。

データの間の","は1つのままでもできると思いますが、
この方がわかりやすいかと。

戻る