使用 AWK 过滤数据帧的行以仅显示给定字段中具有 X 个实例的条目

使用 AWK 过滤数据帧的行以仅显示给定字段中具有 X 个实例的条目

我有一个大数据框,其中字段之一(“ID”)对应于唯一标识符。但是,该值有多个实例,具体取决于附加测量值(“structureA”和“structB”)的二进制组合。我想设计一种使用 awk 过滤行的方法,以显示与初始数据帧中只有 4 个实例的 ID 关联的测量值。

我可以设想分两部分执行此操作,首先使用 uniq -c 或 awk 数组计算实例数量并保存到文件中,然后使用该新文件使用 awk 数组和 FNR==NR 过滤初始数据帧。但我希望 awk 可能有一种方法来统计计数,然后打印一组满足条件的行(例如,一个条目出现 X 次)。

> Initial table
ID  structureA  structureB
sample_1    1   1
sample_2    1   1
sample_2    2   1
sample_2    1   2
sample_2    2   2
sample_3    1   1
sample_3    2   1
sample_3    3   1
sample_4    1   1
sample_4    2   1
sample_4    3   1
sample_4    4   1

> Desired table
ID  structureA  structureB
sample_2    1   1
sample_2    2   1
sample_2    1   2
sample_2    2   2
sample_4    1   1
sample_4    2   1
sample_4    3   1
sample_4    4   1

答案1

感谢 Ed Morton 对 awk 脚本的改进:

awk -v n=$1 '
NR==1
{a[$1]=($1 in a ? a[$1] RS : "") $0}
END{for(i in a){if(gsub(RS,"&",a[i])==n-1){print a[i]}}}
' "$2"

NR==1打印标题。最后一条语句调用 split 函数只是为了检查每个数组元素中有多少行。如果它们是 4,则打印它们。

./script 4 file在使其可执行后,您可以使用(第一个参数是重复次数,第二个参数是文件名)来调用它。

此答案并不强制要求具有相同第一个字段的行必须在输入文件中彼此相邻。

答案2

$ awk -v n=4 '
    NR==1 { print; next }
    $1 != prev { if (cnt==n) printf "%s", buf; prev=$1; cnt=0; buf="" }
    { cnt++; buf=buf $0 ORS }
    END { if (cnt==n) printf "%s", buf }
' file
ID  structureA  structureB
sample_2    1   1
sample_2    2   1
sample_2    1   2
sample_2    2   2
sample_4    1   1
sample_4    2   1
sample_4    3   1
sample_4    4   1

相关内容