linux - 使用 awk 计算每列的平均值,忽略缺失数据

标签 linux bash awk mean missing-data

我有一个大型制表符分隔数据表,其中包含数千行和数十列,并且缺少标记为“na”的数据。例如,

na  0.93    na  0   na  0.51
1   1   na  1   na  1
1   1   na  0.97    na  1
0.92    1   na  1   0.01    0.34

我想计算每列的平均值,但要确保在计算中忽略缺失的数据。例如,第 1 列的平均值应为 0.97。我相信我可以使用 awk,但我不确定如何构建命令来对所有列执行此操作并解释丢失的数据。

我所知道的就是计算单个列的平均值,但它将缺失的数据视为 0,而不是将其排除在计算之外。

awk '{sum+=$1} END {print sum/NR}' filename

最佳答案

这很晦涩,但适用于您的示例

awk '{for(i=1; i<=NF; i++){sum[i] += $i; if($i != "na"){count[i]+=1}}} END {for(i=1; i<=NF; i++){if(count[i]!=0){v = sum[i]/count[i]}else{v = 0}; if(i<NF){printf "%f\t",v}else{print v}}}' input.txt

编辑: 其工作原理如下:

awk '{for(i=1; i<=NF; i++){ #for each column
        sum[i] += $i;       #add the sum to the "sum" array
        if($i != "na"){     #if value is not "na"
           count[i]+=1}     #increment the column "count"
        }                   #endif
     }                      #endfor
    END {                    #at the end
     for(i=1; i<=NF; i++){  #for each column
        if(count[i]!=0){        #if the column count is not 0
            v = sum[i]/count[i] #then calculate the column mean (here represented with "v")
        }else{                  #else (if column count is 0)
            v = 0               #then let mean be 0 (note: you can set this to be "na")
        };                      #endif col count is not 0
        if(i<NF){               #if the column is before the last column
            printf "%f\t",v     #print mean + TAB
        }else{                  #else (if it is the last column)
            print v}            #print mean + NEWLINE
        };                      #endif
     }' input.txt               #endfor (note: input.txt is the input file)

```

关于linux - 使用 awk 计算每列的平均值,忽略缺失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33921031/

相关文章:

AWK 整合文件(后续)

c - 我想在 UNIX 中制作复制功能文件

linux - 符号链接(symbolic link)给 "Permission denied"... 到 root

linux - 在终端中输入空字符

bash - Gitlab-CI:为 Linux 和 Windows 设置环境变量

linux - 如何递归获取目录下所有文件的总大小

awk - awk 是二维数组还是类似于存储值的东西?

linux - awk里面期待

linux - 如何找到目录中最新修改文件的时间戳(递归)?

bash ascii 到十六进制