-2

I have a table that shows how many ASVs(columns) are clustered in one OTU(rows). Each ASV is represented by a value of 1.

#OTUID    ASV_1    ASV_2    ASV_3    ASV_4    ASV_5    ASV_6    ASV_7    ASV_8    ASV_9    ASV_10
OTU1    1    0    0    1    0    0    0    0    0    1
OTU2    0    1    0    0    1    0    0    0    0    0
OTU3    0    0    0    0    0    1    0    1    1    0

I want to summarize the table to the following;

#OTUID    ASVs
OTU1    ASV_1, ASV_4, ASV_10
OTU2    ASV_2, ASV_5
OTU3    ASV_6, ASV_8, ASV_9

kindly help.

2

The following script assumes that you want to print the column names for all columns on each input line (after the first header line) which have the value 1.

#!/usr/bin/perl

use strict;

my @titles=();

while(<>) {
  if ($. == 1) {
     @titles = split;         # get column titles
     print "#OTUID\tASVs\n";  # print the new output header
     next;
  };
  chomp;

  my @F=split;       # split the input line into fields, store in array @F

  my @ASVs=();       # @ASV array holds the titles for each matching field.

  foreach my $asv (1..$#F) {
    push @ASVs, $titles[$asv] if ($F[$asv] == 1);
  };

  print "$F[0]\t", join(",", @ASVs), "\n";
}

save it as, e.g., alex.pl, make it executable with chmod +x alex.pl and run it like so:

$ ./alex.pl input.txt 
#OTUID  ASVs
OTU1    ASV_1,ASV_4,ASV_10
OTU2    ASV_2,ASV_5
OTU3    ASV_6,ASV_8,ASV_9
  • Worked like magic. Thanks #cas – alex kiarie Sep 6 at 6:28
1
$ perl -lane '$,="\t";
   $. == 1 and do{ $h{$_} = $F[$_] for 1..$#F; print $F[0], "ASVs"; next; };
   print $F[0], join ", ", map { $h{$_} } grep { $F[$_] == 1 } 1..$#F;
' file

Results:

#OTUID  ASVs
OTU1    ASV_1, ASV_4, ASV_10
OTU2    ASV_2, ASV_5
OTU3    ASV_6, ASV_8, ASV_9

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.