将函数应用于矩阵中的每对列之间的每20行

时间:2013-11-12 02:14:38

标签: r loops matrix genetics

我有一组遗传SNP数据,如下所示:

Founder1 Founder2 Founder3 Founder4 Founder5 Founder6 Founder7 Founder8 Sample1 Sample2 Sample3 Sample...
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T
A A A T T T T T A T A T   

矩阵的大小为56列乘46482行。我需要首先每20行对矩阵进行分区,然后将前8列(创建者)中的每一列与每列9-56进行比较,并将匹配的字母/等位基因的总数除以总行数(20)。最终我需要48 8列乘2342行矩阵,它们基本上是相似矩阵。我试图通过以下方式分别提取每一对:

"length(cbind(odd[,9],odd[,1])[cbind(odd[,9],cbind(odd[,9],odd[,1])[,1])[,1]=="T" & cbind(odd[,9],odd[,1])[,2]=="T",])/nrow(cbind(odd[,9],odd[,1]))"

但这远远不够高效,而且我不知道将这个函数应用到每20行和多对中的更快的方法。

在上面给出的例子中,如果所有行都相同,如20行所示,那么Sample1矩阵的第一行将是:

1 1 1 0 0 0 0 

1 个答案:

答案 0 :(得分:0)

我认为这就是你想要的?它有助于将问题分解为更小的部分,然后重复将功能应用于这些部分。我的解决方案需要几分钟才能在我的笔记本电脑上运行,但我认为应该给你或其他人一个开始。如果您正在寻找更好的速度,我建议您查看data.table包。我确信还有其他方法可以使代码下面的代码更快。

# Make a data set of random sequences
rows = 46482
cols = 56
binsize = 20
founder.cols = 1:8
sample.cols = setdiff(1:cols,founder.cols)
data = as.data.frame( matrix( sample( c("A","C","T","G"), 
                                      rows * cols, replace=TRUE ), 
                              ncol=cols ) )

# Split the data into bins
binlevels = gl(n=ceiling(rows/binsize),k=20,length=rows)
databins = split(data,binlevels)

# A function for making a similarity matrix
compare_cols = function(i,j,mat) mean(mat[,i] == mat[,j])
compare_group_cols = function(mat, group1.cols, group2.cols) {
  outer( X=group1.cols, Y=group2.cols, 
        Vectorize( function(X,Y) compare_cols(X,Y,mat) ) )
}

# Apply the function to each bin
mats = lapply( databins, compare_group_cols, sample.cols, founder.cols )

# And just to check. Random sequences should match 25% of the time. Right?
hist( vapply(mats,mean,1), n=30 ) # looks like this is the case