Shell 具有不同行大小的多个文件的标准偏差
我有几个行大小不同的文件,但每个文件中的列数是相同的。e、 g ifile1.txtShell 具有不同行大小的多个文件的标准偏差,shell,awk,standard-deviation,Shell,Awk,Standard Deviation,我有几个行大小不同的文件,但每个文件中的列数是相同的。e、 g ifile1.txt 1 1001 ? ? 2 1002 ? ? 3 1003 ? ? 4 1004 ? ? 5 1005 ? 0 6 1006 ? 1 7 1007 ? 3 8 1008 5 4
1 1001 ? ?
2 1002 ? ?
3 1003 ? ?
4 1004 ? ?
5 1005 ? 0
6 1006 ? 1
7 1007 ? 3
8 1008 5 4
9 1009 3 11
10 1010 2 9
ifile2.txt
1 2001 ? ?
2 2002 ? ?
3 2003 ? ?
4 2004 ? ?
5 2005 ? 0
6 2006 6 12
7 2007 6 5
8 2008 9 10
9 2009 3 12
10 2010 5 7
11 2011 2 ?
12 2012 9 ?
ifile3.txt
1 3001 ? ?
2 3002 ? 6
3 3003 ? ?
4 3004 ? ?
5 3005 ? 0
6 3006 1 25
7 3007 2 3
8 3008 ? ?
在每个文件中,第一列表示索引号,第二列表示ID。
我想从第三列开始计算每个索引编号的标准偏差
所需输出:
1 ? ? ---- [Here ? is computed from ?, ?, ?] So answer is ?
2 ? ? ---- [Here 6 is computed from ?, ?, 6] So answer is ? as only one sample
3 ? ?
4 ? ?
5 ? 0.00 ----- [Here 0 is computed from 0, 0, 0] So answer is as all are same value
6 3.54 12.01
7 2.83 1.15
8 2.83 4.24 ----- [Here 7 is computed from 5, 9, ?]
9 0.00 0.71
10 2.12 1.41
11 ? ?
12 ? ?
我正在尝试更改以下适用于平均值的脚本(复制自)
为了计算std,您需要将第3列上的原始数字保存到NF。您可以尝试的一种方法是将它们连接到数组值中(请参见下面代码中的
v
),然后在最终计算结束块时进行拆分以检索它们,例如:
$ cat test.awk
{
nMax = FNR > nMax ? FNR : nMax # get the max FNR from all files
for (j=3; j<=NF; j++) {
if ($j == "?") continue
v[FNR, j] = v[FNR, j] == "" ? $j : v[FNR, j] FS $j # concatenate values of (FNR,j) in `v` using FS
t[FNR, j] += $j # calculate total for each (FNR,j)
}
}
END {
for (i=1; i<=nMax; i++) {
printf("%d\t", i)
for (j=3; j<=NF; j++) {
if ((i,j) in t) { # if (i,j) exists, split v into vals using default FS
n = split(v[i,j], vals)
if (n == 1) { # print "?" if only 1 item in array vals
printf("?")
} else { # otherwise, calculate mean `e`, sum `s` and then std
e = t[i,j]/n
s = 0
for(x in vals) s += (vals[x]-e)**2
printf("%.2f", sqrt(s/(n-1)))
}
} else { # print "?" if (i,j) not exists
printf("?")
}
printf(j==NF?"\n":"\t")
}
}
}
为了计算std,您需要将第3列上的原始数字保存到NF。您可以尝试的一种方法是将它们连接到数组值中(请参见下面代码中的
v
),然后在最终计算结束块时进行拆分以检索它们,例如:
$ cat test.awk
{
nMax = FNR > nMax ? FNR : nMax # get the max FNR from all files
for (j=3; j<=NF; j++) {
if ($j == "?") continue
v[FNR, j] = v[FNR, j] == "" ? $j : v[FNR, j] FS $j # concatenate values of (FNR,j) in `v` using FS
t[FNR, j] += $j # calculate total for each (FNR,j)
}
}
END {
for (i=1; i<=nMax; i++) {
printf("%d\t", i)
for (j=3; j<=NF; j++) {
if ((i,j) in t) { # if (i,j) exists, split v into vals using default FS
n = split(v[i,j], vals)
if (n == 1) { # print "?" if only 1 item in array vals
printf("?")
} else { # otherwise, calculate mean `e`, sum `s` and then std
e = t[i,j]/n
s = 0
for(x in vals) s += (vals[x]-e)**2
printf("%.2f", sqrt(s/(n-1)))
}
} else { # print "?" if (i,j) not exists
printf("?")
}
printf(j==NF?"\n":"\t")
}
}
}
我真诚地相信,如果你想让别人为你做这项工作,最好是提供一些东西(比如财政支持)作为交换。非常感谢你的评论。我面临困难,所以在这里发布问题并寻找答案。如果stackoverflow需要金钱支持作为交换,那么也可以罚款。但是我从来没有在发帖时看到过这样的选择。我真诚地相信,如果你想让别人为你做这项工作,最好是提供一些东西(比如资金支持)作为交换。非常感谢你的评论。我面临困难,所以在这里发布问题并寻找答案。如果stackoverflow需要金钱支持作为交换,那么也可以罚款。但我在发帖时从未见过这样的选择。
$ cat test.awk
{
nMax = FNR > nMax ? FNR : nMax # get the max FNR from all files
for (j=3; j<=NF; j++) {
if ($j == "?") continue
v[FNR, j] = v[FNR, j] == "" ? $j : v[FNR, j] FS $j # concatenate values of (FNR,j) in `v` using FS
t[FNR, j] += $j # calculate total for each (FNR,j)
}
}
END {
for (i=1; i<=nMax; i++) {
printf("%d\t", i)
for (j=3; j<=NF; j++) {
if ((i,j) in t) { # if (i,j) exists, split v into vals using default FS
n = split(v[i,j], vals)
if (n == 1) { # print "?" if only 1 item in array vals
printf("?")
} else { # otherwise, calculate mean `e`, sum `s` and then std
e = t[i,j]/n
s = 0
for(x in vals) s += (vals[x]-e)**2
printf("%.2f", sqrt(s/(n-1)))
}
} else { # print "?" if (i,j) not exists
printf("?")
}
printf(j==NF?"\n":"\t")
}
}
}
$ awk -f test.awk ifile*.txt
1 ? ?
2 ? ?
3 ? ?
4 ? ?
5 ? 0.00
6 3.54 12.01
7 2.83 1.15
8 2.83 4.24
9 0.00 0.71
10 2.12 1.41
11 ? ?
12 ? ?