有条件地查找列名以填充r

时间:2016-10-12 03:43:58

标签: r

我有一个看起来像这样的data.frame:

   A C  G T
1  6 0 14 0
2  0 0 20 0
3 14 0  6 0
4 14 0  6 0
5  6 0 14 0

(实际上,我有1800个不同行数......)

只是为了解释你在看什么: 每行是一个SNP,因此它可以是一个碱基(A,C,G,T)或另一个碱基(A,C,G,T) SNP1的主要等位基因是“G”,其出现在14个个体中,次要等位基因是“A”,其出现在数据集中的20个个体中的6个中。 在SNP1处显示G的14个个体与SNP3处的显示A相同,因此沿着5行组合碱基有两种可能性:一种是GGAAG,一种是AGGGA。 这些(理论上)可以从相应行中包含6或14的所有单元格的名称构建,结果如下:

   A C  G T 14 6
1  6 0 14 0  G A
2  0 0 20 0  G G
3 14 0  6 0  A G
4 14 0  6 0  A G
5  6 0 14 0  G A

有没有一种优雅的方式来实现这样的目标? 我从一个有点related question的答案中得到一段代码,它将返回矩阵中特定值的位置。

    mat <- matrix(c(1:3), nrow = 4, ncol = 4)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    1
[2,]    2    3    1    2
[3,]    3    1    2    3
[4,]    1    2    3    1

    find <- function(mat, value) {
      nr <- nrow(mat)
      val_match <- which(mat == value)
      out <- matrix(NA, nrow= length(val_match), ncol= 2)
      out[,2] <- floor(val_match / nr) + 1
      out[,1] <- val_match %% nr
      return(out)
    }

    find(mat, 2)

     [,1] [,2]
[1,]    2    1
[2,]    1    2
[3,]    0    3
[4,]    3    3
[5,]    2    4

我想我可以弄清楚如何将其调整到从原始data.frame返回colname的位置,但它需要它作为输入寻找的值。 - 在一个数据片段中可能存在多个(如上例14和6中所示),并且/它们对于我的数据的每个片段都是不同的。 在其中一些中,根本没有重复。 此外,如果其中一个值达到20,那么相应的colname将自动选择(如上例中的第2行所示)。

修改 我已经尝试过thelatemail建议的代码,它可以在某些数据上正常工作,但不适用于所有数据。

例如,这个产生了我不完全理解的结果: 子集看起来像这样:

    A C G T
 1  0 0 3 1
 2  0 9 0 3
 3  3 0 0 2
 4  0 3 0 2
 5  2 0 0 3
 6  0 2 0 3

    sel <- subset > 0
    ord <- order(row(subset)[sel], -subset[sel])
    haplo1 <- split(names(subset)[col(subset)[sel]][ord], row(subset)[sel][ord])

这会产生

 1
 [1] "G" "T"
 2
 [1] "C" "T"
 3
 [1] "A" "T"
 4
 [1] "C" "T"
 5
 [1] "T" "A"
 6
 [1] "T" "C"

由于每一行都有3个,我不明白为什么这些不是全部在这些可能性中(这将导致GTACTT和TCTTAC)。

我也意识到我有很多缺失的等位基因,只有一两个人被发现在这个位点有一个基地。 可以使用&#34;缺少的列#34;以某种方式包括在内? - 我试图解决它,这给了我一个关于非对应行号的错误。

2 个答案:

答案 0 :(得分:1)

为了使我的最小功能起作用,我不得不将零转换为NA。出于某种原因,na.rm = TRUE不适用于哪个.min

看看这对你有用:

A <- c(6,0,14,14,6)
C <- c(0,0,0,0,0)
G <- c(14,20,6,6,14)
T <- c(0,0,0,0,0)
mymatrix <- as.matrix(cbind(A,C,G,T))
mymatrix<-ifelse(mymatrix==0,mymatrix==NA,mymatrix)
mymatrix

major_allele <- colnames(mymatrix)[apply(mymatrix,1,which.max)] ; head(major_allele)
minor_allele <- colnames(mymatrix)[apply(mymatrix,1,which.min)] ; head(minor_allele)

myds<-as.data.frame(cbind(mymatrix,major_allele,minor_allele))
myds


> myds
     A    C  G    T major_allele minor_allele
1    6 <NA> 14 <NA>            G            A
2 <NA> <NA> 20 <NA>            G            G
3   14 <NA>  6 <NA>            A            G
4   14 <NA>  6 <NA>            A            G
5    6 <NA> 14 <NA>            G            A

答案 1 :(得分:1)

这是一项尝试,无论每行中有多少次点击都会有效。它返回一个列表对象,这可能适用于每行不同的结果长度。

sel <- dat > 0
ord <- order(row(dat)[sel], -dat[sel])
split(names(dat)[col(dat)[sel]][ord], row(dat)[sel][ord] )
#List of 5
# $ 1: chr [1:2] "G" "A"
# $ 2: chr "G"
# $ 3: chr [1:2] "A" "G"
# $ 4: chr [1:2] "A" "G"
# $ 5: chr [1:2] "G" "A"

dat的位置:

dat <- read.table(text="
   A C  G T
1  6 0 14 0
2  0 0 20 0
3 14 0  6 0
4 14 0  6 0
5  6 0 14 0
", header=TRUE)