2016-08-10 4 views
3

私はさまざまなリスト要素を持つ何百ものテキストファイルを持っています(千単位)。簡略化された3つの代表的なファイルが以下に示されています(ここでは行の要素は色です)コンティンジェンシーテーブルを作成する

group1.txt

red 
blue 
red 
green 
pink 
red 

group2.txt

yellow 
brown 
cyan 
yellow 
brown 
red 
violet 
orange 

group3.txt

orange 
violet 
pink 
cyan 
grey 

は、私は以下のスクリプトでソートカウントテーブルを作成することができます -

awk -F '\t' '{print $1}' * | sort | uniq -c | sort -nr 

>

4 red 
    2 yellow 
    2 violet 
    2 pink 
    2 orange 
    2 cyan 
    2 brown 
    1 grey 
    1 green 
    1 blue 

私は次のように分割表を作成したい -

Colour group1 group2 group3 
red  3 1 0 
green 1 0 0 
blue 0 0 0 
yellow 0 2 0 
orange 0 1 1 
grey 0 0 1 
violet 0 1 1 
pink 1 0 1 
brown 0 2 
cyan 0 1 1 

にはどうすればいいのawk、パイソン、PerlやRを使用して、この分割表を作成することができますか?

+2

あなたはファイル数として数3は一例であり、あなたが持っていることを含まなければなりません多くのファイルを処理します。 – simbabque

答えて

5

これは、ファイル(これはちょうど私たちはで動作するように例を持っている - 分割表を構築するため、実際の機械の一部ではない)を設定R.

でのソリューションです:

writeLines(c("red","blue","red","green","pink","red"), 
      con="group1.txt") 
writeLines(c("yellow","brown","cyan","yellow","brown","red", 
      "violet","orange"), 
      con="group2.txt") 
writeLines(c("orange","violet","pink","cyan","grey"), 
      con="group3.txt") 
を作品のほとんどはに読み、データを配置している

:...我々は、ファイルがNNが数値であるgroupNN.txtと呼ばれていることを知っているとしましょう

flist <- list.files(pattern="group[0-9]+.txt") 
grpnames <- gsub("\\.txt$","",flist) 

の読むカラーファイル:グループIDの

col_list <- lapply(flist,scan,what="character") 

マッチングベクトル:

今だけ tableを使用
grpvec <- rep(grpnames,sapply(col_list,length)) 

table(unlist(col_list),grpvec) 
##  grp 
## col  group1 group2 group3 
## blue  1  0  0 
## brown  0  2  0 
## cyan  0  1  1 
## green  1  0  0 
## grey  0  0  1 
## orange  0  1  1 
## pink  1  0  1 
## red   3  1  0 
## violet  0  1  1 
## yellow  0  2  0 

(これはアルファベット順に並べています。私はあなたにとってそれがどれほど重要かはわかりません...)

+0

ありがとう@ベン。限られた数の行要素(ここでは色)がある場合には素晴らしいソリューションです。しかし、何百もの一意の行要素がある場合、引数writeLines(c( "red"、 "blue"、 "red"、 "green"、 "pink"、 "red")、con = "group1.txt")実用的ではありません。代わりに? – panbar

+2

これらの行は、ファイルを作成するだけのもので、再現可能な例が得られるようになっています。すでにデータファイルがある場合は不要です。 –

+0

downvoterがコメントしたいと思っているなら、私は問題を解決しようとしています。 –

4

awk救助に!

真の多次元配列のためのGNU AWK、gensub(有
$ awk 'FNR==1{c++} 
      {counts[$1,c]++; keys[$1]} 
      END{print "Colour Group1 Group2 Group3"; 
       for(k in keys) {printf "%s ",k; 
           for(i=1;i<=c;i++) printf "%s ", counts[k,i]+0; 
           print ""}}' file{1,2,3} | 
    column -t 

Colour Group1 Group2 Group3 
red  3  1  0 
pink 1  0  1 
orange 0  1  1 
blue 1  0  0 
violet 0  1  1 
yellow 0  2  0 
grey 0  0  1 
cyan 0  1  1 
brown 0  2  0 
green 1  0  0 
+1

はい、良いアイデア! – karakfa

1

)、およびARGIND:

$ cat tst.awk 
{ cnt[$0][ARGIND]++ } 
END { 
    printf "%s%s", "Colour", OFS 
    for (groupNr=1; groupNr<=ARGIND; groupNr++) { 
     printf "%s%s", gensub(/\.[^.]+$/,"",1,ARGV[groupNr]), (groupNr<ARGIND ? OFS : ORS) 
    } 

    for (colour in cnt) { 
     printf "%s%s", colour, OFS 
     for (groupNr=1; groupNr<=ARGIND; groupNr++) { 
      printf "%d%s", cnt[colour][groupNr], (groupNr<ARGIND ? OFS : ORS) 
     } 
    } 
} 

$ awk -f tst.awk group1.txt group2.txt group3.txt | column -t 
Colour group1 group2 group3 
orange 0  1  1 
cyan 0  1  1 
brown 0  2  0 
grey 0  0  1 
red  3  1  0 
yellow 0  2  0 
violet 0  1  1 
pink 1  0  1 
green 1  0  0 
blue 1  0  0 
関連する問題