¿Cómo agrega columnas desde una hoja de cálculo y luego genera porcentajes en Perl?
Frecuentes
Visto 103 veces
0
Tengo muchos datos en un formato como este.
Amistad Academy District Amistad Academy 596 812 73.4
Andover School District Andover 39 334 11.7
Ansonia School District Ansonia High School 427 732 58.3
Ansonia School District Ansonia Middle School 219 458 47.8
Ansonia School District Mead School 431 642 67.1
Ansonia School District Prendergast School 504 787 64
Lo que tengo que hacer es juntar un grupo de distritos escolares y luego tomar la última columna, sumar todos los distritos coincidentes (todos los de Ansonia, por ejemplo) y luego dividir ese número por la suma de la penúltima columna. No tengo problemas para poner los distritos escolares en archivos separados. Eso fue solo un grep. Ahora, sin embargo, estoy atascado y pensando que podría ser más fácil hacerlo en Excel. He estado jugando con soluciones en perl como
1 #!/opt/local/bin/perl
2 use strict;
3 use warnings;
4 use ARGV::readonly;
5
6 my @data;
7 my @headers - split ',', <>;
8
9 while (<>) {
10 my @row = split;
11 $data[$_] += $row[$_] for (0 .. $#row);
12 }
13
14 $" = "\t";
15 print "@headers", "\n";
16 print "@data";
pero no puedo entender la sintaxis para hacer la suma y la división.
Gracias.
2 Respuestas
1
Estás sumando cada columna. Solo quieres sumar dos de ellos. De lo contrario, estás prácticamente allí.
my $sum_last = 0; # Use better name.
my $sum_penu = 0; # Use better name.
while (<>) {
chomp;
my @row = split /\t/;
next if $row[0] ne 'Ansonia School District';
$sum_last += $row[-1];
$sum_penu += $row[-2];
}
say $sum_last / $sum_penu;
contestado el 22 de mayo de 12 a las 18:05
0
El programa a continuación seleccionará los valores del archivo y mantendrá los totales acumulados para cada distrito escolar en un hash. El contenido del hash se imprime cuando se han leído todos los datos. Funciona desde el archivo sin filtrar; no es necesario que lo grep en fuentes separadas.
Noté que sus datos parecen estar separados por tabulaciones, y es importante usar split /\t/
para que los campos que contienen caracteres de espacio no se dividan también.
No dice qué significan los datos, por lo que no puedo hacer que el código sea más legible.
Por favor, vuelva a preguntar si tiene más preguntas.
use strict;
use warnings;
open my $fh, '<', 'myfile' or die $!;
scalar <$fh>; # lose header record
my %data;
while (<$fh>) {
my @fields = split /\t/;
my $district = shift @fields;
$data{$district}[0] += $fields[-2];
$data{$district}[1] += $fields[-1];
}
for my $district (sort keys %data) {
printf "%s - %f\n", $district, $data{$district}[1] / $data{$district}[0];
}
salida
Andover School District - 0.035030
Ansonia School District - 0.090569
contestado el 22 de mayo de 12 a las 18:05
Hmm, esto no produce errores pero tampoco produce nada más. Cambié myfile al nombre de archivo correcto pero no parece estar produciendo ningún resultado. Sin embargo, creo que este es el awnser. Me mantendré en ello. - edwardiglesias
Deberías hacer algo de depuración. print "@fields\n"
dentro del bucle para ver lo que estás leyendo. ¿Has copiado el código exactamente? Sin el scalar
el <$fh>
comerá todos los datos y no dejará nada para el ciclo. - Borodin
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas regex perl sum or haz tu propia pregunta.
¿Esto es tarea? No tenemos ningún problema en ayudar con la tarea, pero especifique si es así, podemos ajustar nuestras respuestas en consecuencia. - ikegami
No deberes. Mi esposa es investigadora de una fundación educativa. Tontamente le dije que esto sería mucho más fácil con un guión simple. - edwardiglesias
@edward: no te preocupes: le diré que todo fue tu propio trabajo :) - Borodin