如何在r中更改异构双字母

时间:2016-02-26 16:04:35

标签: r

我有一个数据框:

DF = read.table(text="S01   S02     S03    S04    S05   S06
TT     CC     TT     CT     TT     00
AC     AA     AC     CC     AA     AA
CC     TC     CC     TT     CC     00
CC     AC     CC     AC     AA     CC
GG     00     TG     TT     GG     TG
GG     GA     GG     GA     GG     GG", header=T, stringsAsFactors=F)

我想以更快的方式将所有异构值(双字母)更改为双倍“00”。 结果预期:

S01   S02     S03    S04    S05   S06
TT     CC     TT     00     TT     00
00     AA     00     CC     AA     AA
CC     00     CC     TT     CC     00
CC     00     CC     00     AA     CC
GG     00     00     TT     GG     00
GG     00     GG     00     GG     GG

感谢任何帮助!

5 个答案:

答案 0 :(得分:5)

我将假设这是基因数据。这样可以很容易地构造所有异构基对,并使用正则表达式替换它们:

as.data.frame(gsub("^(.)(?!\\1).$","00", as.matrix(DF), perl=T))
#   S01 S02 S03 S04 S05 S06
# 1  TT  CC  TT  00  TT  00
# 2  00  AA  00  CC  AA  AA
# 3  CC  00  CC  TT  CC  00
# 4  CC  00  CC  00  AA  CC
# 5  GG  00  00  TT  GG  00
# 6  GG  00  GG  00  GG  GG

OR

bases <-c("A","C","G","T")
b1 <- rep(bases, 4)
b2 <- rep(bases, each=4)
hetero<- paste0(b1[b1!=b2],b2[b2!=b1])

DF[] <- lapply(DF,gsub, pattern=paste0(hetero,collapse="|"),replacement="00")

基准

因为基准测试很有趣,并且在这个线程中有很多不同的解决方案。令人惊讶的结论:差异不是很大,获胜者是DavidH(第二名康拉德)。

包含1000列和1000行的数据框的结果:

m <- as.matrix(DF)
m[m %in% hetero] <- "00"
res <- as.data.frame(m)

答案 1 :(得分:3)

您可以使用负向前瞻性正则表达式

mov AX, 4
ret

答案 2 :(得分:2)

由于您表示您更喜欢快速解决方案,我尝试避免使用正则表达式并替换级别:

ex <- expand.grid(c("A","T","C","G"),c("A","T","C","G"))
ex <- ex[ex[1]!=ex[2],]
het.combs <- apply(ex,1,function(i) {paste0(i[1],i[2])} )
map <- setNames( rep("00",length(het.combs)) , het.combs )
fac.df<- lapply(DF, as.factor)

fac.df <- lapply(fac.df, function(i){levels(i)[levels(i) %in% names(map)] <- map[levels(i)[levels(i) %in% names(map)]];i } )
DF <- as.data.frame(fac.df)

答案 3 :(得分:2)

只需创建一个“纯合”碱基的载体,并使用它来索引数据。不幸的是,这种索引仅适用于矩阵(而不是数据帧),因此我们会相应地转换数据。

bases = c('A', 'C', 'G', 'T')
homozygous = apply(cbind(bases, bases), 1, paste, collapse = '')

DF = as.matrix(DF)
DF[! DF %in% homozygous] = '00'

或者,您只需在数据框的每个列上使用ifelse即可。实际上,这种方法比矩阵方法简单,并且可能更快。这里的显着部分是你根本不需要使用正则表达式 - 事实上,完全没有理由使用正则表达式进行精确匹配。

DF = data.frame(lapply(DF, function (x) ifelse(x %in% homozygous, x, '00')))

答案 4 :(得分:2)

首先,我要感谢Heroka的基准测试比较,David的快速解决方案以及MrFlick的简洁脚本。我还要感谢所有其他答案。根据您的解决方案,我有一个更快速的解决方案,它结合了MrFlick和David H的解决方案。阅读DF后,stringsAsFactors=T

DF <- data.frame(lapply(DF, function(x) {
  levels(x) <- gsub("^(.)(?!\\1).$","00", levels(x), perl=T)
  return(x)
}))