【发布时间】:2021-05-11 11:49:56
【问题描述】:
以下 AWK 脚本(作为 bash 代码的一部分)从 input.csv 的选定列中提取数字,并对这些数字进行一些简单的统计操作,最终将结果保存为 output.csv 中的 1 行:
awk -F ", *" ' # set field separator to comma, followed by 0 or more whitespaces
FNR==1 {
if (n) { # calculate the results of previous file
m = s / n # mean
var = s2 / n - m * m # variance
if (var < 0) var = 0 # avoid an exception due to round-off error
mean[suffix] = m # store the mean in an array
rmsd[suffix] = sqrt(var)
lowest[suffix] = min # lowest dG
highest[suffix] = fourth # dG in cluster with highest pop
}
prefix=suffix=FILENAME
sub(/_.*/, "", prefix)
sub(/\/[^\/]+$/, "", suffix)
sub(/^.*_/, "", suffix)
s = 0 # sum of $3
s2 = 0 # sum of $3 ** 2
n = 0 # count of samples
min = 0 # lowest value of $3 (assuming all $3 < 0)
max = 0 # highest value of $2 (assuming all $2 > 0)
}
FNR > 1 {
s += $3
s2 += $3 * $3
++n
if ($3 < min) min = $3 # update the lowest value
if ($2 > max) {
max = $2 # update popMAX
fourth = $3 # update the value of dG corresponded to topPOP
}
}
END {
if (n) { # just to avoid division by zero
m = s / n
var = s2 / n - m * m
if (var < 0) var = 0
mean[suffix] = m
rmsd[suffix] = sqrt(var)
lowest[suffix] = min # most negative dG
highest[suffix] = fourth # dG in a cluster with pop(MAX)
}
print "Lig(CNE)", "dG(min)", "dG(popMAX)", "dG(mean)"
for (i in mean)
printf "%s %.2f %.2f %.2f\n", i, lowest[i], highest[i], mean[i]
}' input.csv > output.csv
在使用 input.csv(如下所示)进行操作时,它会从日志的第三列 (dG) 中提取数字:i) 检测第三列 (dG(min) 中的最小值,该最小值始终对应于ID=1),以及第二列最大数对应的dG个数(POPmax):
# input.csv from the folder 10V1_cne_lig12
ID, POP, dG
1, 142, -5.6500 # this is dG min to be extracted
2, 10, -5.5000
3, 2, -4.9500
4, 150, -4.1200 # this is dG corresponded to pop(MAX) to be extracted
最后将结果保存在另一个多列的 output.csv 文件中,其中包含每个已处理 CSV 的部分名称(对应的前缀用作行的 ID),以及有关其 dG(min )、dG(popMAX) 以及为第 3 (dG) 列中的所有数字计算的平均值:
# output.csv
Lig(CNE) dG(min) dG(popMAX) dG(mean)
lig12 -5.65 -4.12 −5.055
所以 dG(min) 是 input.csv 中 ID=1 的行中 $2 (dG) 的数量(最低 dG),dG(popMAX) 对应于该行中检测到的值 dG,它具有最高值2 美元(POP)
我需要修改脚本的 AWK 部分,在 output.csv 中添加两个附加列,其中包含有关每个对应 dG 值的 input.csv (POP) 的第二列的信息(取自第三列同一日志的列)。所以同样的日志应该是这样的
# output.csv
Lig(CNE). dG(min) POP(min) dG(popMAX) POP(max) dG(mean)
lig12 -5.65 (142) -4.12 (150) −5.055
在其他世界中,除了在第 3 列执行的操作之外,我还需要考虑第 2 列中的数字,然后在 output.csv 中匹配它们:所以 POP(min) 应该取自第一行的 $2(带有 dG(min) )和 POP(max) 从带有 dG(popMAX) 的行的 $2。
我尝试使用
定义第二列信息'{print $2}'
但结果 output.csv 与原始 input.csv 的行顺序不匹配(例如,它从不属于 dG(min) 等的行中取出第二列)
【问题讨论】:
-
您确实意识到
for (i in mean)循环以不同于创建顺序的顺序遍历关联数组? -
你是对的!非常感谢您的友好评论,我刚刚编辑了 AWK 代码,实际上我忘记在其中添加一部分 AWK 脚本,该脚本也计算 dG 列的平均值并将值存储在数组中!
标签: awk