You may try something like this:
(use should use nawk or /usr/xpg4/bin/awk on Solaris)
func mode(list, sep, n, a, i, h, m, v) {
sep = sep ? sep : FS
n = split(list, a, sep)
while (++i <= n) {
if (++h[a] > m) {
m = h[a]
v = a
}
}
return m > 1 ? v : "#N/A"
}
For example:
% cat file
32,45,56,32,32
32,45,56,30,92
% awk -F, '{ print mode($0) }
func mode(list, sep, n, a, i, h, m, v) {
sep = sep ? sep : FS
n = split(list, a, sep)
while (++i<= n) {
if (++h[a] > m) {
m = h[a]
v = a
}
}
return m > 1 ? v : "#N/A"
}' file
32
#N/A
What should the function return for an input like the one below?
radulov - it is bimodal, really. It should return a set: (1,2). I don't know what Excel does, just what statistics does. Mode is often used for data like 'birthdays of people in the room' or 'last names of people in a town' - data unlike numbers or numeric data with no real inherent meaning, just magnitude. Football (soccer) scores qualify in that category.
Thanks Jim,
I was not sure if it was supposed to return N/A or a set.
If I'm not missing something again:
% cat file
32,45,56,32,32
32,45,56,30,92
1,1,2,2
% awk -F, '{ print mode($0) }
func mode(list, sep, n, a, i, h, m, k, f, r) {
sep = sep ? sep : FS
n = split(list, a, sep)
while (++i <= n) if (++h[a] > m) m = h[a]
for (k in a) m == h[a[k]] && f[a[k]]
if (m > 1) for (k in f) r = r ? r sep k : k
return r ? r : "#N/A"
}' file
32
#N/A
1,2
Some awk interpreters (eg. mawk) do not support the abbreviated form func (you should use function instead).
Try this:
(use nawk or /usr/xpg4/bin/awk on Solaris)
awk>out.txt 'FNR == 1 || $0 = $0 FS mode($0)
func mode(list, sep, n, a, i, h, m, k, f, r) {
sep = sep ? sep : FS
n = split(list, a, sep)
while (++i <= n) if (++h[a] > m) m = h[a]
for (k in a) m == h[a[k]] && f[a[k]]
if (m > 1) for (k in f) r = r ? r sep k : k
return r ? r : "#N/A"
}' file1 file2 ... filen