我有一个8040行的文件,有两列,第二列有可变长度的字符串,范围从30000到200000个字符(DNA序列)。 [以下是150个字符的样本]
X:100670000-101060000 TTCCCCAAACAGCAACTTTAAGGAGCAGCTTCCTTTATGATCCCTGATTGCCTCCCCTTTGTTCCCATAACAAGTAGTTTAAATTTTCTGTTAAAGTCCAAACCACATATTTACAATACCTCGCACC
根据第二列上每个字符串的长度,我想将每个字符串分成10个字符串(字符串长度的10%),计算每个字段的G和C的数量,然后得到G和C的百分比。
例如,如果我的第二列的第一个条目长度为39000个字符,则每个段的长度为3900个字符,代码将计算每个段中G和C的出现次数,添加它们,并除以39000在这种情况下,获得百分比。
我尝试在 AWK 中写这个,但它不起作用。我得到的输出是完整的字符串,而不是段:
awk '{
bp_length[$2]= length($2);
bin_size[$2]= bp_length[$2]*0.1;
for(i=1;i<=bp_length[$2];i+=bin_size[$2]){
print gsub("G", "G")"\t"gsub("C", "C")}
}'
我将此作为输出:
79060 76624
如果输出可以在包含10列的表中表示,并且每列代表每行的10个段,那么在 R 中解决此问题会更容易吗?
答案 0 :(得分:4)
由于您尝试在awk
进行此练习,我会给您一个awk
计划
此示例显示拆分和计数正确完成:
awk '{l=length($2); binsize=int(l/10) + (l%10!=0)
for(i=1;i<=l;i+=binsize) {
str=substr($2,i,binsize)
print str, gsub("G","",str), gsub("C","",str)
}
}' <file>
给我们输出
TTCCCCAAACAGC 1 6
AACTTTAAGGAGC 3 2
AGCTTCCTTTATG 2 3
ATCCCTGATTGCC 2 5
TCCCCTTTGTTCC 1 6
CATAACAAGTAGT 2 2
TTAAATTTTCTGT 1 1
TAAAGTCCAAACC 1 4
ACATATTTACAAT 0 2
ACCTCGCACC 1 6
所以,为了获得百分比:
awk '{ l=length($2); binsize=int(l/10) + (l%10!=0)
printf "%-24s (length: %7d, binsize: %7d, lastbin: %7d)\n",$1,l,binsize,l%binsize
j=1;
for(i=1;i<=l;i+=binsize) {
str=substr($2,i,binsize)
printf "segment %0.3d : %6.3f (%%G) %6.3f (%%C)\n", j++,100*gsub("G","",str)/l, 100*gsub("C","",str)/l
}
}' <file>
,输出为:
X:100670000-101060000 (length: 127, binsize: 13, lastbin: 10)
segment 001 : 0.787 (%G) 4.724 (%C)
segment 002 : 2.362 (%G) 1.575 (%C)
segment 003 : 1.575 (%G) 2.362 (%C)
segment 004 : 1.575 (%G) 3.937 (%C)
segment 005 : 0.787 (%G) 4.724 (%C)
segment 006 : 1.575 (%G) 1.575 (%C)
segment 007 : 0.787 (%G) 0.787 (%C)
segment 008 : 0.787 (%G) 3.150 (%C)
segment 009 : 0.000 (%G) 1.575 (%C)
segment 010 : 0.787 (%G) 4.724 (%C)
答案 1 :(得分:2)
你可以这样做:
# string of length 39000
test <- paste(rep(LETTERS, 1500), collapse = "")
# divide string into 10 equal parts
test2 <- sapply(seq(1, nchar(test), nchar(test)/10), function(x) substr(test, x, x + nchar(test)/10 - 1))
# use str_count from stringr-package to count characters and calculate percentage
library(stringr)
(str_count(test2, "G") + str_count(test2, "C")) / nchar(test) * 100
编辑新请求:
if
未向量化,因此您无法使用它来处理向量bins
(在我的示例中为test2
)。
相反,请将sapply
与ifelse
结合使用。这样,它将遍历十个部分,并在str_count("N") < 10 percent
或NA
的情况下输出计算。代码:
X <- sapply(test2, function(x) ifelse(str_count(x, c("N")) < .1*nchar(x),
(str_count(x, "G") + str_count(x, "C")) / nchar(x) * 100, NA))
names(X) <- seq_along(X)
> X
1 2 3 4 5 6 7 8 9 10
7.692308 7.692308 7.692308 7.692308 7.692308 7.692308 7.692308 7.692308 7.692308 7.692308