テーブルから複数の個別のCSVファイルを作成したいと思います。以下は例表です。
gene REF_S1_host REF_S1_FL S1_host1 S1_host2 S1_FL REF_S2_host REF_S2_FL S2_host1 S2_host2 S2_FL
gene1 1 0 0 0 0 0 0 0 0 0
gene2 1 1 1 1 0 0 0 0 0 0
gene3 0 1 0 0 1 0 0 0 0 0
gene4 1 0 0 0 0 1 0 0 0 0
gene5 0 0 0 0 0 1 0 1 0 0
gene6 1 0 0 0 0 0 0 0 1 1
gene7 0 1 0 0 0 0 0 0 0 1
CSV(または他のタブで区切られたファイル)を作成したいと思います。
「S1」を含む列ヘッダーの下に「1」を含むすべてのデータを抽出しますが、同じ遺伝子の場合、「S2」を含むすべてのヘッダーの値は「0」です。たとえば、
gene REF_S1_host REF_S1_FL S1_host1 S1_host2 S1_FL REF_S2_host REF_S2_FL S2_host1 S2_host2 S2_FL gene1 1 0 0 0 0 0 0 0 0 0 gene2 1 1 1 1 0 0 0 0 0 0 gene3 0 1 0 0 1 0 0 0 0 0
REFファイル(S1またはS2)から値が「1」の行のみを取得しますが、他のすべてのフィールド(「REF」を含まない行ヘッダーなど)に対しては、「0」の行のみを取得します。たとえば、
gene REF_S1_host REF_S1_FL S1_host1 S1_host2 S1_FL REF_S2_host REF_S2_FL S2_host1 S2_host2 S2_FL gene1 1 0 0 0 0 0 0 0 0 0 gene4 1 0 0 0 0 1 0 0 0 0
ここで、REF_S1*には「1」が含まれます。みんなその他(すなわち、REFではない)S1サンプルは「0」+みんなREF_S2*は「0」+ですが、他のS2サンプル(REFではありません)は「1」です。たとえば、
gene REF_S1_host REF_S1_FL S1_host1 S1_host2 S1_FL REF_S2_host REF_S2_FL S2_host1 S2_host2 S2_FL gene6 1 0 0 0 0 0 0 0 1 1 gene7 0 1 0 0 0 0 0 0 0 1
最後に、すべての*FLは「1」、すべての*ホストは「0」です。たとえば、
gene REF_S1_host REF_S1_FL S1_host1 S1_host2 S1_FL REF_S2_host REF_S2_FL S2_host1 S2_host2 S2_FL gene3 0 1 0 0 1 0 0 0 0 0 gene7 0 1 0 0 0 0 0 0 0 1
しかし、どうすればいいのかわかりません。どんな提案でも歓迎します。
ベストアンサー1
私は仮定する
- (多少)示されているように、データはスペースで区切られます。
- テーブルには常に11個の列があります(ただし、行数に制限はないかもしれません)。
- セル値にはスペースは含まれません。 (特に1行(タイトル)と1列(遺伝子)を除くすべての項目は
0
ORです1
。)
にするのは簡単ですawk
。
-
...「S1」を含む列ヘッダーの下に「1」を含むすべてのデータがありますが、同じ遺伝子の場合、「S2」を含むすべてのヘッダーの値は「0」です。
つまり、
-
(2列は1 OR 3列は1 OR 4列は1 OR 5列は1 OR 6列は1)
AND
7列は0
AND
8列は0 AND 9列は0
AND 10列は0 AND 11列は0awk -v OFS=',' ' NR==1 { next } ($2==1 || $3==1 || $4==1 || $5==1 || $6==1) && $7==0 && $8==0 && $9==0 && $10==0 && $11==0 { $1=$1; print } '
OFS
「出力フィールドの区切り記号」。入力がタブ区切りまたはスペースで区切られている場合でも、データをカンマ区切りフィールドに書き込むように指示-v OFS=','
します。awk
- 最初の行(タイトル行)をスキップするように指示します
NR==1 { next }
。awk
ヘッダー行を印刷するにはに変更しますNR==1 { $1=$1; print; next }
。 - 次の2行は、上記のAND / ORロジックをエンコードします。
{ $1=$1; print }
条件が満たされたら、ラインを印刷します。この$1=$1
メソッドは、最初のフィールドを自分と同じに設定します。何も起こらないように聞こえるかもしれません。実際には、awk
新しい(カスタム)出力フィールド区切り文字(カンマで指定)を使用して行を強制的に書き換えることはトリックです。心が変わり、入力に示されているように行を正確に出力するには、-v OFS=','
およびを削除します$1=$1;
。
-
... REFファイル(S1またはS2)には「1」の値があり、他のすべてのフィールドには「0」の値のみを持つ行のみ...
awk -v OFS=',' ' NR==1 { next } ($2==1 || $3==1 || $7==1 || $8==1) && $4==0 && $5==0 && $6==0 && $9==0 && $10==0 && $11==0 { $1=$1; print } '
-
ここで、REF_S1*には「1」が含まれており、他のすべて(つまり非REF)S1サンプルは「0」、すべてのREF_S2 *は「0」ですが、他のすべてのS2サンプル(非REF)は「1」です。
awk -v OFS=',' ' NR==1 { next } ($2==1 || $3==1) && $4==0 && $5==0 && $6==0 && $7==0 && $8==0 && ($9==1 || $10==1 || $11==1) { $1=$1; print } '
-
...すべての*FLは「1」で、すべての*ホストは「0」です。
awk -v OFS=',' ' NR==1 { next } ($3==1 || $6==1 || $8==1 || $11==1) && $2==0 && $4==0 && $5==0 && $7==0 && $9==0 && $10==0 { $1=$1; print } '