2列、3列、1列の連続セルが等しい場合、9列のC_R
合計数を計算しようとします。S_R
ファイルはベッド形式(タブ区切り形式)です。元のファイルは大きく、最初の列は染色体番号を定義します。ファイルの最初の数行は次のとおりです。
chr1 10200 10300 8 10000 10214 100 214 S_R
chr1 10200 10300 8 10009 10233 100 224 S_R
chr1 10200 10300 8 10014 10220 100 206 S_R
chr1 10200 10300 8 10045 10215 100 170 S_R
chr1 10200 10300 8 10068 10209 100 141 S_R
chr1 10200 10300 8 10074 10300 100 226 C_R
chr1 10200 10300 8 10182 10283 100 101 S_R
chr1 10200 10300 8 10182 10387 100 205 C_R
chr1 10300 10400 4 10182 10387 100 205 S_R
chr1 10300 10400 4 10331 10467 100 136 S_R
chr1 10300 10400 4 10346 10461 100 115 S_R
chr1 10300 10400 4 10352 10468 100 116 S_R
chr1 10400 10500 3 10331 10467 100 136 S_R
chr1 10400 10500 3 10346 10461 100 115 S_R
chr1 10400 10500 3 10352 10468 100 116 S_R
chr1 11000 11100 2 11024 11163 100 139 S_R
chr1 11000 11100 2 11024 11188 100 164 S_R
chr1 11100 11200 3 11024 11163 100 139 S_R
chr1 11100 11200 3 11024 11188 100 164 S_R
chr1 11100 11200 3 11127 11296 100 169 S_R
chr1 11200 11300 1 11127 11296 100 169 S_R
chr1 11400 11500 2 11412 11561 100 149 S_R
chr1 11400 11500 2 11457 11608 100 151 S_R
chr1 11500 11600 3 11412 11561 100 149 S_R
chr1 11500 11600 3 11457 11608 100 151 C_R
chr1 11500 11600 3 11574 11744 100 170 S_R
chr1 11600 11700 3 11457 11608 100 151 S_R
chr1 11600 11700 3 11574 11744 100 170 C_R
chr1 11600 11700 3 11640 11815 100 175 S_R
chr1 11700 11800 4 11574 11744 100 170 S_R
chr1 11700 11800 4 11640 11815 100 175 C_R
chr1 11700 11800 4 11784 11963 100 179 S_R
chr1 11700 11800 4 11791 11936 100 145 S_R
上記の表の最初の8行で、列1、2、3が同じであるため、一時出力ファイルは次のようになります。
chr1 10200 10300 2 6
chr1 10300 10400 0 4
chr1 10400 10500 0 3
chr1 11000 11100 0 2
chr1 11100 11200 0 3
chr1 11200 11300 0 1
chr1 11400 11500 0 2
chr1 11500 11600 1 2
chr1 11600 11700 1 2
chr1 11700 11800 1 3
出力ファイルでは、列4C_R
と5は次のようになります。S_R
答え1
awk
これは次の方法で行うことができます。
awk 'function report() {
if (n) print last_key, 0+count["C_R"], 0+count["S_R"]
}
{key = $1 OFS $2 OFS $3}
key != last_key {report(); n = 0; split("", count); last_key = key}
{count[$9]++; n++}
END {report()}' <your-file
-F '\t' -v OFS='\t'
入力フィールドがタブで区切られている場合は、入力ファイルと出力ファイルの区切り文字を追加して指定する必要があります。デフォルトFS
では、入力フィールド区切り文字(によって設定されます-F
)は特別な意味を持つ空白文字です。フィールドを区切る空白のシーケンスと、先頭と末尾の空白が削除されるか、IOW フィールドが空白ではない文字のシーケンスです。したがって、空のフィールドは存在できず、OFS
空白でもあります。これは、単に出力のフィールドがスペースで区切られていることを意味します。
答え2
これはGNU(awk
ほとんどのLinuxシステムのgawk
デフォルト)メソッドです。awk
ここでは、列がタブで区切られていると仮定していますが、これはbedファイルまたはbedpeファイルのように見えるため、どちらもタブが必要なので、これが正しいと合理的に確信しています。
$ gawk -F'\t' -v OFS='\t' -v type1="C_R" -v type2="S_R" '
{
a[$1 OFS $2 OFS $3][$NF]++;
}
END{
for (i in a){
print i,0+a[i][type1],0+a[i][type2]
}
}' file.bed
chr1 11200 11300 0 1
chr1 11700 11800 1 3
chr1 10300 10400 0 4
chr1 11000 11100 0 2
chr1 10400 10500 0 3
chr1 11500 11600 1 2
chr1 11400 11500 0 2
chr1 11100 11200 0 3
chr1 11600 11700 1 2
chr1 10200 10300 2 6
説明する
-F'\t'
入力フィールド区切り記号をタブに設定し、-v OFS='\t'
出力フィールド区切り記号をタブに設定します。次に、スクリプトで使用するtype1
2つの異なる変数を設定します。type2
スクリプトの本文は右a[$1 OFS $2 OFS $3][$NF]++;
。これは、出力フィールド区切り文字(この場合はタブ)で区切られた最初の3つのフィールドをOFS
2D配列の最初のキーとして使用しますa
。 2番目のキーは最後のフィールド($NF
)で、値に1を追加するだけです。したがって、a
配列は、各可能な最後のフィールドで、各文字、開始位置、および終了位置が見つかった回数を計算します。
完了したら、END{ }
ブロック内の配列のすべてのキー(文字、開始位置、終了位置)を繰り返し、次に文字、開始位置、終了位置(値)を持つ2つのa
最後のフィールドをそれぞれ印刷します。 of)、次に、最後の可能な各フィールドが最初の3つのフィールド()で表示される回数です。これらの文字、開始位置、終了位置に特定の最後のフィールドが表示されない場合は、空のフィールドの代わりにエラーが発生する必要があります。type1
type2
i
0+a[i][type1],0+a[i][type2]
0+
0
答え3
TSV認識ユーティリティMiller(mlr
)を使用して入力をヘッダーなしのTSVファイルに読み込み、必要な列のみを選択して(使用cut
)、列9の値を;
各列の組み合わせ1の区切りリストに収集/縮小します。 2と3(使用)を使用して、残りの各レコードについて収集された合計文字列の数を計算しますnest
(式を使用)。 9列の縮小値は最終的に削除されます(with)。C_R
S_R
put
cut -x
mlr --from=file --tsv -N \
cut -f 1,2,3,9 then \
nest --ivar ';' -f 9 then \
put '
a = splita($9,";");
for (k in ["C_R","S_R"]) {
$[k] = count(select(a, func(e) { return e == k }))
}' then \
cut -x -f 9
質問のデータが与えられると、次のタブで区切られた出力が生成されます。
chr1 10200 10300 2 6
chr1 10300 10400 0 4
chr1 10400 10500 0 3
chr1 11000 11100 0 2
chr1 11100 11200 0 3
chr1 11200 11300 0 1
chr1 11400 11500 0 2
chr1 11500 11600 1 2
chr1 11600 11700 1 2
chr1 11700 11800 1 3
答え4
使用幸せ(以前のPerl_6)
~$ raku -e 'my @a = lines.map: *.split(/\s+/); \
my %hash.push: [Z=>] @a.map(*.[0..2]), @a.map(*.[*-1]); \
put join "\t", .key, (.value.map: * eq "C_R")>>.Int.sum, \
(.value.map: * eq "S_R")>>.Int.sum for %hash.sort;' file
これはPerlプログラミング言語の1つであるRakuで書かれた答えです。lines
空白には上記の内容がmap
挿入されています。split
結果は@a
配列に保存されます。%hash
Aを宣言し、[Z=>]
Rakuの縮小メタ演算子を使用して、最初の3つの列と一緒にpush
キー/値のペアをここに追加します。.[0..2]
鍵最後の.[*-1]
列は値。最後のステートメントでは、文字列value
seq
とC_R
sが有効であることを確認してください。各ブール結果は、med列とout列にS_R
変換されます。Int
sum
put
入力例:
chr1 10200 10300 8 10000 10214 100 214 S_R
chr1 10200 10300 8 10009 10233 100 224 S_R
chr1 10200 10300 8 10014 10220 100 206 S_R
chr1 10200 10300 8 10045 10215 100 170 S_R
chr1 10200 10300 8 10068 10209 100 141 S_R
chr1 10200 10300 8 10074 10300 100 226 C_R
chr1 10200 10300 8 10182 10283 100 101 S_R
chr1 10200 10300 8 10182 10387 100 205 C_R
chr1 10300 10400 4 10182 10387 100 205 S_R
chr1 10300 10400 4 10331 10467 100 136 S_R
chr1 10300 10400 4 10346 10461 100 115 S_R
chr1 10300 10400 4 10352 10468 100 116 S_R
chr1 10400 10500 3 10331 10467 100 136 S_R
chr1 10400 10500 3 10346 10461 100 115 S_R
chr1 10400 10500 3 10352 10468 100 116 S_R
chr1 11000 11100 2 11024 11163 100 139 S_R
chr1 11000 11100 2 11024 11188 100 164 S_R
chr1 11100 11200 3 11024 11163 100 139 S_R
chr1 11100 11200 3 11024 11188 100 164 S_R
chr1 11100 11200 3 11127 11296 100 169 S_R
chr1 11200 11300 1 11127 11296 100 169 S_R
chr1 11400 11500 2 11412 11561 100 149 S_R
chr1 11400 11500 2 11457 11608 100 151 S_R
chr1 11500 11600 3 11412 11561 100 149 S_R
chr1 11500 11600 3 11457 11608 100 151 C_R
chr1 11500 11600 3 11574 11744 100 170 S_R
chr1 11600 11700 3 11457 11608 100 151 S_R
chr1 11600 11700 3 11574 11744 100 170 C_R
chr1 11600 11700 3 11640 11815 100 175 S_R
chr1 11700 11800 4 11574 11744 100 170 S_R
chr1 11700 11800 4 11640 11815 100 175 C_R
chr1 11700 11800 4 11784 11963 100 179 S_R
chr1 11700 11800 4 11791 11936 100 145 S_R
出力例:
chr1 10200 10300 2 6
chr1 10300 10400 0 4
chr1 10400 10500 0 3
chr1 11000 11100 0 2
chr1 11100 11200 0 3
chr1 11200 11300 0 1
chr1 11400 11500 0 2
chr1 11500 11600 1 2
chr1 11600 11700 1 2
chr1 11700 11800 1 3
put
すべての列をタブで区切るには、[最後のドアから.key
]に置き換えます。.key.split(" ").join("\t")
中間のステップを見ると非常に理解しやすいことが多いので、次はマイニングの.raku
最後の2列sum
前にデータ()のRakuの内部表現です。
~$ raku -e 'my @a = lines.map: *.split(/\s+/); my %hash.push: [Z=>] @a.map(*.[0..2]), @a.map(*.[*-1]); .raku.say for %hash.sort;' file
"chr1 10200 10300" => $["S_R", "S_R", "S_R", "S_R", "S_R", "C_R", "S_R", "C_R"]
"chr1 10300 10400" => $["S_R", "S_R", "S_R", "S_R"]
"chr1 10400 10500" => $["S_R", "S_R", "S_R"]
"chr1 11000 11100" => $["S_R", "S_R"]
"chr1 11100 11200" => $["S_R", "S_R", "S_R"]
"chr1 11200 11300" => "S_R"
"chr1 11400 11500" => $["S_R", "S_R"]
"chr1 11500 11600" => $["S_R", "C_R", "S_R"]
"chr1 11600 11700" => $["S_R", "C_R", "S_R"]
"chr1 11700 11800" => $["S_R", "C_R", "S_R", "S_R"]