ほとんどの列がありますが、以下のテキストファイルがあります。持っているものを抽出したい特定の割合/数量TRUE 値の数。たとえば、9行のうち2つにTRUE列(TRUE / FALSE値を含む)が含まれています。
または、列を抽出する方が良いです。少なくともTRUE値の特定の数(例:2)。上記の例では、列にTRUE値を持つ2〜9行の行があります。さまざまな行数のファイルに一般化する必要があります。
ありがとうございます!
入力ファイルの例:
Comparison MT group1 group1.1 group1.2 group1.3 group1.4 group1.5 group1.6 group1.7 group1.8 group1.9
BP:HA FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
CB:HA FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
HA:PI TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
AL:GR FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
AL:LA TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
AL:PL FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
GR:PP FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
LA:PP TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
PL:PP FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
TRUE値が2つ以上の列の望ましい結果:
結果ファイル:
MT
group1
group1.9
答え1
すべての列をスキャンし、各列に「TRUE」の数を累積します。
最後に、設定点以上のすべての列を印刷します。
#!/bin/bash
awk -vprop="${1:-0.3}" '
NR==1{split($0,fields);next};
{for(i=2;i<=NF;i++){ if($i=="TRUE" ){t[i]++};
if($i=="FALSE"){f[i]++}
}
}
END{
for(j in t)
if( (1/(1+f[j]/t[j])) >= prop){
printf("%-10s\t%s\t%s\n",fields[j],j,1/(1+f[j]/t[j]) )
}
}' infile
実行時(提供されたデータについて):
$ ./script 0.001
MT i=2 t=3 f=6 p=0.333
group1 i=3 t=2 f=7 p=0.222
group1.8 i=11 t=1 f=8 p=0.111
group1.9 i=12 t=3 f=6 p=0.333
列2(MT)にはTRUE値が1つ以上(実際には3つ)あります。
列3(グループ1)にはTRUE値が2つあります。
列11(group1.8)にはTRUE値が1つあります。列12(group1.9)には3つのTRUE値があります。
スケールを指定しない場合、デフォルトは0.3です。
$ ./script
MT i=2 t=3 f=6 p=0.333
group1 i=3 t=2 f=7 p=0.222
group1.9 i=12 t=3 f=6 p=0.333
答え2
bashを使用して十分なインスタンスを持つ列を選択する1つの方法は次のとおりですTRUE
。
min_true=3; \
max_col=12; \
for col in $(seq 2 $max_col); do \
sed 's, ,.,g;s, ,.,g' "$filename" | \
tail -n+2 | \
cut -d. -f$col > /tmp/f; \
count=$(grep TRUE /tmp/f | wc -l); \
if [ "$count" -ge "$min_true" ]; then \
echo "Column $(($col-1)): $count out of $(echo $(wc -l </tmp/f))"; \
cat /tmp/f; \
fi; \
done
「3 of 9」などの文字列の出力をgrepして列番号を取得できます(0から計算を開始)。
Column 1: 3 out of 9
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
答え3
$ awk -v p='10' 'NR==1 { split($0,cols); next }
{
for (i=2; i<=NF; ++i)
nt[i] += ($i == "TRUE" ? 1 : 0 )
}
END {
for (i=2; i<=NF; ++i) {
cp = 100*nt[i]/NR
if (cp > p) printf("%-20s %.2f%%\n", cols[i], cp)
}
}' file
MT 30.00%
group1 20.00%
group1.9 30.00%
プログラムawk
は、列ヘッダーを表示するために必要な割合である1つのパラメーターを使用しますp
。TRUE
最初の行から始めて、すべての列ヘッダーを配列に保存しますcols
。次に、TRUE
その単語が各列に表示される回数を合計します。最後に、TRUE
各列の行の割合を計算し、cp
それをと比較しますp
。与えられたp
値より大きい場合、列名とパーセンテージを出力します。