una tablas sumar rangos por hoja grupos expandir esquematizar esquemas dinamicas datos cálculo crear contraer como celdas agrupar perl awk

perl - tablas - expandir y contraer celdas en excel



Contraer filas con múltiples campos (4)

Tengo este código:

awk ''!seen[$1,$2]++{a[$1]=(a[$1] ? a[$1]", " : "/t") $2} END{for (i in a) print i a[i]} '' inputfile

y me gustaría trabajar para colapsar filas con más de dos campos, pero siempre basar en el primer campo como índice.

Archivo de entrada (delimitado por tabulaciones de tres columnas):

protein_1 membrane 1e-4 protein_1 intracellular 1e-5 protein_2 membrane 1e-50 protein_2 citosol 1e-40

Salida deseada (delimitada por tabulaciones de tres columnas):

protein_1 membrane, intracellular 1e-4, 1e-5 protein_2 membrane, citosol 1e-50, 1e-40

¡Gracias!

Apilar aquí:

awk ''!seen[$1,$2]++{a[$1]=(a[$1] ? a[$1]"/t" : "/t") $2};{a[$1]=(a[$1] ? a[$1]", " : "/t") $3} END{for (i in a) print i a[i]} '' 1 inputfile


Con GNU awk para matrices en 2-D:

$ gawk '' { a[$1][$2] = $3 } END { for (i in a) { printf "%s", i sep = "/t" for (j in a[i]) { printf "%s%s", sep, j sep = ", " } sep = "/t" for (j in a[i]) { printf "%s%s", sep, a[i][j] sep = ", " } print "" } }'' file protein_1 membrane, intracellular 1e-4, 1e-5 protein_2 membrane, citosol 1e-50, 1e-40


Realmente espero que alguien publique algo de awk wizardry, pero voy a seguir adelante y descartar el script de perl de forma más larga por ahora:

use strict; use warnings; my @cols = (); my $lastprotein = ''''; while (<DATA>) { chomp; my ($protein, @data) = split "/t"; if ($protein ne $lastprotein && @cols) { print join("/t", $lastprotein, map {join '', '', @$_} @cols), "/n"; @cols = (); } push @{$cols[$_]}, $data[$_] for (0..$#data); $lastprotein = $protein; } print join("/t", $lastprotein, map {join '', '', @$_} @cols), "/n"; __DATA__ protein_1 membrane 1e-4 protein_1 intracellular 1e-5 protein_2 membrane 1e-50 protein_2 citosol 1e-40

Salidas

protein_1 membrane, intracellular 1e-4, 1e-5 protein_2 membrane, citosol 1e-50, 1e-40


Esto debería funcionar para usted:

awk ''{ col1[$1]++ for(fld = 2; fld <= NF; fld++) { line[$1,fld] = (line[$1,fld]) ? line[$1,fld] ", " $fld : $fld } } END { for(name in col1) { printf "%s/t", name for(item = 2; item <= NF; item++) { printf "%s/t", line[name,item] } print "" } }'' file

Salida :

protein_1 membrane, intracellular 1e-4, 1e-5 protein_2 membrane, citosol 1e-50, 1e-40


perl -lane'' $ar = $h{shift @F} ||= []; push @{$ar->[$_]}, $F[$_] for 0,1; END { $" = ", "; print "$_/t@{$h{$_}[0]}/t@{$h{$_}[1]}" for sort keys %h; } '' file

salida

protein_1 membrane, intracellular 1e-4, 1e-5 protein_2 membrane, citosol 1e-50, 1e-40