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