How to calculate the average of each column with Tcl script

338 Views Asked by At

I need to calculate the average of each column with a tcl script from a text file please help me

Frame Time     Elec     VdW         Nonbond     Total
0      0     -216.63   -16.0174    -232.647    -232.647 
1      1     -196.786  -28.6093    -225.395    -225.395 
2      2     -277.05   -23.924     -300.974    -300.974 
3      3     -203.854  -30.2473    -234.101    -234.101
1

There are 1 best solutions below

2
On

Once you start dealing with many columns, it gets easier to pull the whole file into memory. (This works well even for surprisingly large files.)

# Read the lines in
set f [open $filename]
set lines [split [string trim [read $f]] "\n"]
close $f

# Do an initial clean up of the data; \S+ matches non-whitespace
set headers [regexp -all -inline {\S+} [lindex $lines 0]]
set data [lmap line [lrange $lines 1 end] {regexp -all -inline {\S+} $line}]
# Properly we'd also validate the data to handle non-numeric junk, but this is just an example...

Now we can define a procedure to get the average of a column by name:

proc columnAverage {name} {
    global headers data
    # Look up which column it is
    set idx [lsearch -exact $headers $name]
    if {$idx < 0} {
        error "no such column \"$name\""
    }
    # Get the data from just that column
    set column [lmap row $data {lindex $row $idx}]
    # Calculate the mean of the column: sum / count
    return [expr {[tcl::mathop::+ {*}$column] / double([llength $column])}]
}

You'd call that like this:

puts "average of Elec is [columnAverage Elec]"