【问题标题】:Extract values in two different columns matching in other columns in R提取与 R 中其他列匹配的两个不同列中的值
【发布时间】:2015-09-21 00:29:32
【问题描述】:

我有这个矩阵叫做mymat(大约446664 X 234的暗淡)。它有 REFALT 列,它们可以有任何 A、T、G、C 字母(只有一个字母)。在以.GT 结尾的列中,我想替换这些字母。要匹配的条件是,如果有 0,我想用 REF 列中的字母替换它,如果有 1,那么我想用 ALT 列中的字母替换它。如果有 NA,我想用“0”“0”替换它(即零空间零)。最后,我需要将所有 .GT 列反转(转置),如结果所示。结果,一切都被空格隔开。

 mymat<-structure(c("G", "A", "C", "A", "G", "A", "C", "T", "G", "A", 
"1/1", "0/0", "0/0", "NA", "NA", "0,15", "8,0", "8,0", "NA", 
"NA", "1/1", "0/1", "0/0", "NA", "NA", "0,35", "12,12", "15,0", 
"NA", "NA"), .Dim = 5:6, .Dimnames = list(c("chrX:133511988:133511988:G:A:snp", 
"chrX:133528116:133528116:A:C:snp", "chrX:133528186:133528186:C:T:snp", 
"chrX:133560301:133560301:A:G:snp", "chrX:133561242:133561242:G:A:snp"
), c("REF", "ALT", "02688.GT", "02688.AD", "02689.GT", "02689.AD"
)))

结果

02688.GT  A A A A C C 0 0 0 0
02689.GT  A A A C C C 0 0 0 0 

【问题讨论】:

  • 如果一列有缺失值,那么所有列都有缺失值?
  • @atiretoo 不,事实并非如此,它独立于任何列并且可以具有任何值。
  • 所以结果中的行可以有不同的长度?
  • @atiretoo 不,长度也将相同。
  • 怎么样?带有 0/0 或 1/0 的条目......哦。对。

标签: r algorithm matrix


【解决方案1】:

你可以试试:

library(dplyr)
library(stringi)

## convert to data.frame 
data.frame(mymat, check.names = FALSE) %>%
  ## replace the values ("0", "1", "/", "NA") in all columns ending with ".GT" with
  ## the corresponding values in "REF" and "ALT" (" " for "/" and "0 0" for "NA")
  mutate_each(funs(stri_replace_all(., REF, fixed = "0")), ends_with(".GT")) %>%
  mutate_each(funs(stri_replace_all(., ALT, fixed = "1")), ends_with(".GT")) %>%
  mutate_each(funs(stri_replace_all(., " ", fixed = "/")), ends_with(".GT")) %>%
  mutate_each(funs(stri_replace_all(., "0 0", fixed = "NA")), ends_with(".GT")) %>%
  ## keep only the columns ending with ".GT"
  select(ends_with(".GT")) %>%
  ## transpose the results
  t()

这给出了:

         [,1]  [,2]  [,3]  [,4]  [,5] 
02688.GT "A A" "A A" "C C" "0 0" "0 0"
02689.GT "A A" "A C" "C C" "0 0" "0 0"

【讨论】:

  • 谢谢,但有没有办法在不将其更改为数据框(仅使用矩阵)的情况下做到这一点。
  • 你能解释一下步骤吗?
  • @MAPK 是的,可以在不转换为 data.frame 的情况下做到这一点,但这是我首先想到的解决方案。欢迎其他人发布不同的方法。有关每个步骤的说明,请参阅编辑。
【解决方案2】:

所以这只是部分答案,我不知道它对 > 200000 行的效果如何。但也许更聪明的人会想出如何做得更好。

temp1 = strsplit(mymat[,3],"/")
reps = sapply(temp1,length)
refalt = data.frame(REF = rep(mymat[,1],times=reps),ALT = rep(mymat[,2],times=reps),ZERO = "0 0")
GT1 = unlist(temp1)
GT1[GT1=="NA"] = "2"
GT1 = as.numeric(GT1)+1
paste(refalt[cbind(1:8,GT1)]," ")

它是不完整的,因为我们需要将它包装在一个可以传递给 apply() 或 lapply() 的函数中,并在行首捕获变量名。

【讨论】:

    【解决方案3】:

    我正在发布自己的答案,但速度很慢,因此需要进一步优化。

           letters <- strsplit(paste(mymat[,"REF"],mymat[,"ALT"],sep=","),",") # concatenate the letters to have an index to work on from the numbers
    values <- t(mymat[,c(which(colnames(mymat)%in%lapply(all.samples,function(x)(paste(x,"GT",sep=".")))))]) # working on each column needing values
    nbval <- ncol(values) # Keeping track of total number of columns and saving the length of values 
    
    #Preparing the two temp vectors to be used below
    chars <- vector("character",2) 
    ret <- vector("character",nbval)
    
    #Loop over the rows (and transpose the result)
    mydata<-t(sapply(rownames(values),
                     function(x) { 
                       indexes <- strsplit(values[x,],"/") # Get a list with pairs of indexes
    
                       for(i in 1:nbval) { # Loop over the number of columns :/
                         for (j in 1:2) { # Loop over the pair 
                           chars[j] <- ifelse(indexes[i] == "NA", 0,letters[[i]][as.integer(indexes[[i]][j])+1]) # Get '0' if "NA" or the letter with the correct index at this postion
                         }
                         ret[i] <- paste(chars[1],chars[2], sep=" ") # concatenate the two chars
                       }
                       return(ret) # return this for this row
                     }
    ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      相关资源
      最近更新 更多