2016-06-01 11 views
0

私は40000列以上のデータファイルを持っています。ヘッダーでは、各列の名前はC1、c2、...、cnで始まり、cの各セットは1つまたは複数のサブセット、たとえばc1を持ちます。 2つの部分集合を有する。私はcの各セットの最初の列(サブセット)を削除する必要があります。データファイルの列の各セットの最初のサブセットを削除するにはどうすればよいですか?

入力:入力がどのように見える場合、たとえば

c1.31012 c2.87634 c2.22233 c3.44444 
    1 0   0   0   1  
    2 1   0   1   1  
    3 1   0   1   0  
    4 0   0   0   0  
    5 0   0   0   0  
    6 0   0   0   0  
    7 1   0   0   0  

どれ提案して下さい:

c1.20022 c1.31012 c2.44444 c2.87634 c2.22233 c3.00444 c3.44444 
    1 1   0   1   0   0   0   1  
    2 0   1   0   0   1   0   1  
    3 0   1   0   0   1   1   0  
    4 1   0   1   0   0   1   0  
    5 1   0   1   0   0   1   0  
    6 1   0   1   0   0   1   0  

を私は、出力は次のようになる必要がありますか?

update:行の数字の間に空白がない場合(私のデータセットの実際の状況です)、どうすればよいですか? 入力:

c1.20022 c1.31012 c2.44444 c2.87634 c2.22233 c3.00444 c3.44444 
     1 1010001  
     2 0100101  
     3 0100110  
     4 1010010  
     5 1010010  
     6 1010010  

と出力:私の平均は、私の実際のデータは次のように見えることである

c1.31012 c2.87634 c2.22233 c3.44444 
     1 0001  
     2 1011  
     3 1010  
     4 0000  
     5 0000  
     6 0000  
     7 1000  
+0

ループ、リスト内の各サブセットの最初のヘッダの列番号を記録(またはハッシュでキーとして)。次に、すべての行をループし、すべての列をループし、リストにある列をスキップします。 – Barmar

答えて

2

Perlのソリューション:それはまず、ヘッダ行を読み込む前に、列名を抽出するために正規表現を使用しています点を保持し、保持する列番号のリストを保持します。次に、索引を使用して、ヘッダーおよび残りの行から必要な列のみを印刷します。

#!/usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

my @header = split ' ', <>; 
my $last = q(); 
my @keep; 
for my $i (0 .. $#header) { 
    my ($prefix) = $header[$i] =~ /(.*)\./; 
    if ($prefix eq $last) { 
     push @keep, $i + 1; 
    } 
    $last = $prefix; 
} 
unshift @header, q(); 
say join "\t", @header[@keep]; 

while (<>) { 
    my @columns = split; 
    say join "\t", @columns[@keep]; 
} 

更新:最初の行を介して

#!/usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

my @header = split ' ', <>; 
my $last = q(); 
my @keep; 
for my $i (0 .. $#header) { 
    my ($prefix) = $header[$i] =~ /(.*)\./; 
    if ($prefix eq $last) { 
     push @keep, $i; 
    } 
    $last = $prefix; 
} 
say join "\t", @header[@keep]; 

while (<>) { 
    my ($line_number, $all_digits) = split; 
    my @digits = split //, $all_digits; 
    say join "\t", $line_number, join q(), @digits[@keep]; 
} 
+0

ありがとうございます。行内のdigitdの間にタブがない場合、そのプログラムをどのように変更する必要がありますか?実際にはヘッダーを除いて私の実際のデータでは、subsequest行ではすべての数字が次のようにお互いの隣にあります:最初の行:0001.この場合、プログラムの一部を変更する必要がありますか? – zara

+0

@zara:行番号を削除して、 '//'で分割し、 '" \ t "'に参加させず、 '' 'または' q() 'を使う必要があります。 – choroba

+0

実際のデータで最初のスクリプトを実行すると、次のエラーが表示されます:./first.perl行21、<>行3986の結合または文字列での初期化されていない値の使用。このエラー?私のデータは3986行あります。これは問題になる可能性がありますか? – zara

関連する問題