以下是我的意见:
chr1 58962 -0.042053 -22.525086 -20.817409 -19.525688
chr1 58989 -0.014479 -14.459352 -12.824315 -11.744024
chr1 59155 -0.062963 -13.810858 -12.749009 -12.102778
chr1 59256 -0.014105 -7.371202 -9.117587 -11.525907
我在bash中寻找一种方法来获取每行的最大值的索引。我不想考虑前两列。
我可以在R:
中非常简单地完成data=fread(myfile)
maxindex=apply(data[,3:6],1,which.max)
这样输出就是一个包含索引的数组。这是我想要的那种输出。在这种情况下:
maxindex= 1 1 1 1
不幸的是整个文件是32 Gb(包含300000行和8183列的大表),因此即使在我补贴原始文件之后R也无法接受它。我已经读到bash不能按行工作,但还有办法做我想做的事吗?
答案 0 :(得分:2)
使用以下 awk 解决方案,它将 更快 而不是 perl < / em> 方法(在&#34;大&#34;文件):
awk '{ m=$3; p=1; for(i=4;i<=NF;i++) {
if ($i>m) { m=$i; p=i-2 } } printf "%d ",p }' file > max_indices
m=$3
- 初始最大值(第3个字段值)
for(i=4;i<=NF;i++)
- 迭代剩余字段
if ($i>m) { m=$i; p=i-2 }
- 捕获最大值
答案 1 :(得分:0)
Perl解决方案:
perl -ane '$r = 2;
for my $i (3 .. $#F) {
$r = $i if $F[$i] > $F[$r];
}
print $r - 1, " ";
' < input-file > output-file
-n
逐行处理输入行-a
将空格上的每一行拆分为@F数组$r
存储最大值的索引(在处理每一行之前设置为2)答案 2 :(得分:0)
如果你想用基本的bash操作编写脚本,你可以这样做:
#!/bin/bash
# Function to find the max-value of a one-dimensional array
findMax()
{
[[ -z $2 ]] && return # Exit early if the string is empty
declare -a pararr=($@) #Insert the input into an array we can work with
# Basic brute-force algorithm to find the highest value in the array
maxInd=2
for (( i = 3; i < $#; i++ )); do
(( $(echo "${pararr[$i]} > ${pararr[$maxInd]}" | bc) )) && maxInd=$i
done
echo -n " $(( maxInd - 2 ))"
}
echo -n "Maxindex:"
# Feed our findMax row-by-row from the input file
while read -r line; do
findMax $line
done < ${!#}
echo # Append newline at the end
此脚本采用格式化为您的示例的文件,并逐行搜索最大索引。但是,在文件中,每行必须与换行符分隔,如你的示例所示,否则可能会发生一些不稳定的事情。如果您愿意,您当然可以扩展脚本以处理其他格式。
但是,如果您想对非常大的文件执行此操作,我认为其他人提供的解决方案将更适合。我不太了解bash的开销,因为我在大多数性能关键的应用程序中都使用C / C ++,但我猜它并不是很有效。
(( $(echo "${pararr[$i]} > ${pararr[$maxInd]}" | bc) )) && maxInd=$i
这部分脚本真的很难看,但我不知道有什么更好的方法来做浮点运算。我们在这里做的是我们正在评估我们目前在行中的当前位置,我们目前发现的价值最大。所以这个:
echo "${pararr[$i]} > ${pararr[$maxInd]}
可能会扩展到类似的东西
0.356 > 1.567
然后我们将它传递给bc
,它为我们进行浮点比较。如果我们当前的位置大于我们到目前为止找到的最大值,我们将maxIndex设置为该值。希望这会有所帮助。