Awk based script to find the median of all individual columns in a data file


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Awk based script to find the median of all individual columns in a data file
# 1  
Old 06-08-2012
Awk based script to find the median of all individual columns in a data file

Hi All,

I have some data like below.

Code:
Step1,Param1,Param2,Param3
1,2,3,4
2,3,4,5
2,4,5,6
3,0,1,2
3,0,0,0
3,2,1,3

........

so on

Where I need to find the median(arithmetic) of each column from Param1...to..Param3 for each set of Step1 values.
(Sort each specific column, if the total entries is even; my mean is sum of (Middle 2 values)/2 else the mean is the middle value itself.)

I got one script like below by searching in google
Code:
echo -e '6\n2\n4\n3\n1' | sort -n | awk '{arr[NR]=$1}
   END { if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}'

But this works on a single column of data.

I want someone to modify this or suggest some other code to make it work on all columns.

I want something like below

awk -F, -v VAR="$i" '$1==VAR{Some Condition}' input.csv

where I am scanning variable i (each unique value from column1) using for loop.

The Expected output is :

Median_of_Col2,Median_of_Col3,Median_of_Col4 etc.. (practically i have many columns in my input)

Code:
The output with the above input is

2,3,4
3.5,4.5,5.5
0,1,2

Thanks
Sidda
# 2  
Old 06-08-2012
With gawk version 4:
Code:
gawk4 -F, '{
  for (i = 1; i <= NF; ++i)
    a[i][NR] = $i
}
END {
  for (i = 1; i <= NF; ++i) {
    asort(a[i])
    printf(" %.1f", NR%2? a[i][(NR+1)/2] : (a[i][NR/2] + a[i][NR/2+1])/2)
  }
  print ""
}'

# 3  
Old 06-08-2012
The data must be put into order some way in order to get the median, and the sort command can only change the order of lines, it can't swap bits of lines around for you.

awk, unless you're in Linux, doesn't have an easy way to sort data inside itself.

Perhaps perl would be a better solution here.

Code:
$ cat data

Step1,Param1,Param2,Param3
1,2,3,4
2,3,4,5
2,4,5,6
3,0,1,2
3,0,0,0
3,2,1,3

$ cat median.pl

#!/usr/bin/perl

@arr=split(/,/, $header=<STDIN>);       # Count columns
my $dat=[], $row=0, $cols=scalar(@arr), $median, $prefix="";

while(@arr=split(/,/, <STDIN>))
{
        for($n=0; $n<=scalar(@arr); $n++)
        {       $dat[$n][$row]=$arr[$n];        }

        $row++;
}

# Sort each column separately, then get the median and print
for($n=0; $n<$cols; $n++)
{
        @l=sort {$a <=> $b} @{$dat[$n]};        # sort $dat[$n] into @l

        if(($row%2)==0) # Even number of rows
        {
                printf("%s%s", $prefix, ($l[($row/2)-1]+$l[($row/2)])/2);
        }
        else
        {       printf("%s%s", $prefix, $l[$row/2]);    }
        $prefix=",";
}

printf("\n");

exit 0;

$ ./median.pl < data

2.5,2,2,3.5

$

# 4  
Old 06-08-2012
I am getting syntax error !!

Hi binlib,

Thanks for your quick reply.
I am getting some syntax error in the code you code using gawk.
I am unable to figure it after few changes also.
Can you please try to look into it once more and correct the error.


Thanks
Sid

---------- Post updated at 10:45 PM ---------- Previous update was at 10:43 PM ----------

Hi Corona,

This perl script is not giving desired output.
I try to guess the median values how it calculated, but no clue.
What I need is for each unique value in Column1( Step) I need the median values for the remaining columns printed side by side.
I have given my required output in my post.
Can you look into your code again.

Thanks
# 5  
Old 06-08-2012
It works absolutely fine for me using the data you posted, as you can see from what I posted unless you disagree with the numbers it gives. You only gave the format of the data you wanted, you didn't show what values you should get from your input, so I've got no way to check the numbers until you do.

Please show the manner in which you used it, the manner in which it 'did not work', and an actual sample of the data it doesn't work with.

Quote:
each unique value
So duplicates do not count? That's different than just a median of values...
# 6  
Old 06-09-2012
The output computation is shown below.

Hi Corona,

Thanks for the reply.
For the input of
Step1,Param1,Param2,Param3 1,2,3,4 2,3,4,5 2,4,5,6 3,0,1,2 3,0,0,0 3,2,1,3
The output is computed like below.
In 1st column(Step1), for the data sample '1' the median for 2,3,4 columns are 2,3,4 itself (as the columns has only one value(odd number).
Similarly for the data sample '2' (repeated twice) the median is (3+4)/2, (4+5)/2, (5+6)/2 which is nothing but 3.5,4.5,5.5.
Similarly for the data sample '3' (repeated thrice) the median for 2,3,4 columns are 0,1,2 as the total number samples in each column(2,3,4) are 3. ( So when we sort each column the values are like this {0,0,2}, {0,1,1}, {0,2,3} so the median for each set is 0,1,2 respectively).
So the final output will be
2,3,4 # Median of columns 2,3,4 when 1st col rows=='1' 3.5,4.5,5.5 #Median of columns 2,3,4 when 1st col rows =='2' 0,1,2 #Median of columns 2,3,4 when 1st col rows=='3'
# So my result is nothing for median of columns 2,3,4 for each unique set of row values in column1.


I hope the median computation is clearly explained now.
Have a look and let me know.

Regards
Sid

---------- Post updated at 04:49 PM ---------- Previous update was at 05:38 AM ----------

Hi Binlib,

Your code is perfect except for two missing ';'s (semicolons),
one after the statement " a[i][NR] = $i "
and one more after the statement " asort(a[i]) "

Thanks a lot for your effort.

Sidda
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Advanced & Expert Users

Need Optimization shell/awk script to aggreagte (sum) for all the columns of Huge data file

Optimization shell/awk script to aggregate (sum) for all the columns of Huge data file File delimiter "|" Need to have Sum of all columns, with column number : aggregation (summation) for each column File not having the header Like below - Column 1 "Total Column 2 : "Total ... ...... (2 Replies)
Discussion started by: kartikirans
2 Replies

2. Shell Programming and Scripting

awk script to find data in three file and perform replace operation

Have three files. Any other approach with regards to file concatenation or splitting, etc is appreciated If column55(billngtype) of file1 contains YMNC or YPBC then pick the value of column13(documentnumber). Now find this documentnumber in column1(Billdoc) of file2 and grep the corresponding... (4 Replies)
Discussion started by: as7951
4 Replies

3. Shell Programming and Scripting

In PErl script: need to read the data one file and generate multiple files based on the data

We have the data looks like below in a log file. I want to generat files based on the string between two hash(#) symbol like below Source: #ext1#test1.tale2 drop #ext1#test11.tale21 drop #ext1#test123.tale21 drop #ext2#test1.tale21 drop #ext2#test12.tale21 drop #ext3#test11.tale21 drop... (5 Replies)
Discussion started by: Sanjeev G
5 Replies

4. Shell Programming and Scripting

Find columns in a file based on header and print to new file

Hello, I have to fish out some specific columns from a file based on the header value. I have the list of columns I need in a different file. I thought I could read in the list of headers I need, # file with header names of required columns in required order headers_file=$2 # read contents... (11 Replies)
Discussion started by: LMHmedchem
11 Replies

5. UNIX for Dummies Questions & Answers

Median calculator based on id match

I am trying to calculate the median of a column of numbers if they match an ID type on a different column. The input file has 3 columns. The column that has the ID is column 1 and the column with the values I'd like to find the median for is column 3. The file does not need to be sorted. What I... (9 Replies)
Discussion started by: verse123
9 Replies

6. Shell Programming and Scripting

awk script to split file into multiple files based on many columns

So I have a space delimited file that I'd like to split into multiple files based on multiple column values. This is what my data looks like 1bc9A02 1 10 1000 FTDLNLVQALRQFLWSFRLPGEAQKIDRMMEAFAQRYCQCNNGVFQSTDTCYVLSFAIIMLNTSLHNPNVKDKPTVERFIAMNRGINDGGDLPEELLRNLYESIKNEPFKIPELEHHHHHH 1ku1A02 1 10... (9 Replies)
Discussion started by: viored
9 Replies

7. Shell Programming and Scripting

Help with awk replacing identical columns based on another file

Hello, I am using Awk in UBUNTU 12.04. I have a file like following with three fields and 44706 rows. F1 A A F2 G G F3 A T I have another file like this: AL_1 F1 A A AL_2 F1 A T AL_3 F1 A A AL_1 F2 G G AL_2 F2 G A AL_3 F2 G G BO_1 F1 A A BO_2 F1 A T... (6 Replies)
Discussion started by: Homa
6 Replies

8. Shell Programming and Scripting

awk based script to ignore all columns from a file which contains character strings

Hello All, I have a .CSV file where I expect all numeric data in all the columns other than column headers. But sometimes I get the files (result of statistics computation by other persons) like below( sample data) SNO,Data1,Data2,Data3 1,2,3,4 2,3,4,SOME STRING 3,4,Inf,5 4,5,4,4 I... (9 Replies)
Discussion started by: ks_reddy
9 Replies

9. Shell Programming and Scripting

awk based script to find the average of all the columns in a data file

Hi All, I need the modification for the below mentioned code (found in one more post https://www.unix.com/shell-programming-scripting/27161-script-generate-average-values.html) to find the average values for all the columns(but for a specific rows) and print the averages side by side. I have... (4 Replies)
Discussion started by: ks_reddy
4 Replies

10. Shell Programming and Scripting

awk based script to print the "mode(statistics term)" for each column in a data file

Hi All, Thanks all for the continued support so far. Today, I need to find the most occurring string/number(also called mode in statistics terminology) for each column in a data file (.csv type). For one column of data(1.txt) like below Sample 1 2 2 3 4 1 1 1 2 I can find the mode... (6 Replies)
Discussion started by: ks_reddy
6 Replies
Login or Register to Ask a Question