我有一个包含超过2000行和45001列的数据文件。
第一列实际上是一个解释数据类型的“字符串”。
从第2列开始,直至列#45001,数据被重新命名为
“1”
或
“0”
例如,一行中的数据模式为
(0 0 0
1 1
01 1 1
01 1 1 1
0 0 01
0 01 1 1
0 0)
数据的总数是25.在该数据行中,有5个子组,它们仅由数字“1”组成,例如(11
111
1111
1
111
)。子组之间的“0”被假定为“分隔符”。所有“1”的总数是= 13.
我想计算
的比例(所有“1”的总数/仅由“1”组成的子组总数)
那是
(13/5)。
我尝试使用此代码计算所有“1”的总和;
awk -F '0' '{print NF}' < inputfile.in
这给出了值13。
但我不知道如何进一步从这里开始计算我想要的比例。 我不知道如何找到每一行内的子组数量,因为“1”和“0”的出现次数是随机的。
希望得到一些帮助来解决这个问题。
提前感谢任何帮助。
答案 0 :(得分:1)
我从描述中不清楚输入文件的格式是什么。假设输入如下:
$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
计算1的数量和1的组数并取其比例:
$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; print s1/s2}' file
2.6
假设文件中的一行全部为零:
$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
对于第二行,两个和都为零,这将导致除以零的误差。我们可以通过添加if
语句来避免这种情况,该语句将打印比例(如果存在)或0/0
不存在:
if (s2>0)print s1/s2; else print s1"/"s2
完整的代码现在是:
$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; if (s2>0)print s1/s2; else print s1"/"s2}' file
2.6
0/0
代码使用三个变量。 f
是一个标志,如果我们当前在一组1中则为真(1),否则为假(0)。 s1
是该行的数量。 s2
是该行上的一组数量。
f=0;s1=0;s2=0
在每一行的开头,我们初始化变量。
for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}
我们遍历从字段2开始的行上的每个字段。如果字段包含1,我们递增计数器s1
。如果该字段为1并且是新组的开头,我们会增加s2
。
if (s2>0)print s1/s2; else print s1"/"s2}
如果我们遇到至少一个,我们打印比率s1/s2
。否则,我们会打印0/0
。
答案 1 :(得分:1)
这是awk
,可以满足您的需求:
cat file
data 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
data 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
data 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
data 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BMR_10@O24-BMR_6@O13-H13 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1
data 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1
awk '{$1="";$0="0 "$0" 0";t=split($0,b,"1")-1;gsub(/ +/,"");n=split($0,a,"[^1]+")-2;print (n?t/n:0)}' t
2.6
0
25
11
5.5
3