2013-09-10 79 views
0

這是一個非常基本的問題......我確信它寫在這裏的某處......我試圖創建一個新變量(遺傳學數據)檢查指定變量中的「字符串」表達式是否包含在其他幾個變量中

例如(對於那些不知道遺傳學的人): 對於一個家庭(每行一個),我有父親,母親和孩子基因型表示爲A/G,G/A,G/G(作爲單獨的變量)。我想創建一個新的0/1或False/True變量,告訴我孩子的等位基因1是否在母親基因型的任一等位基因中出現,或者在父親基因型的任一等位基因中出現。同樣對於等位基因2.

我嘗試使用regexpr如下,以R:

vcf_GT$MVLR <- regexpr(c(sapply(strsplit(as.character(vcf_GT[,10]),"/"),function(x) x[1])), 
(sapply(strsplit(as.character(vcf_GT[,10]),"/"),function(x) x[2])), 
(c(c(sapply(strsplit(as.character(vcf_GT[,9]),"/"),function(x) x[1])), 
(sapply(strsplit(as.character(vcf_GT[,9]),"/"),function(x) x[2])), 
c(sapply(strsplit(as.character(vcf_GT[,8]),"/"),function(x) x[1])), 
(sapply(strsplit(as.character(vcf_GT[,8]),"/"),function(x) x[2]))))) > 0 

與代表兒童的基因型的柱10,及圖9和圖8分別表示母親和父親的。這很乏味,我可能忘記了這裏的括號。

必須有一個更簡單的方法來檢查與母親和父親的孩子的基因型。

在此先感謝!

P.S.如果我沒有道理 - 我會嘗試添加更多細節。

編輯:雖然我的代碼實際上是一個巨大的線,按要求我增加了回報,它更容易閱讀(不過,它的種很難不管:))

+3

我鼓勵你在代碼中使用空格和回車符。它使我們可讀並可爲您調試! – Justin

+0

併發布一些輸入數據與所需的輸出也會很好。 –

回答

0

如果你想要的是簡單地看匹配母親或父親的等位基因,你不一定需要正則表達式能夠做到這一點。您可以使用%in%運算符(也稱爲match()函數)執行此操作,但我更喜歡此語法。

讓我們設置我們的基因型數據框。請注意,最後一個「家庭」是孩子與母親有不同等位基因的地方。

x <- data.frame(list(mom = c("A/G", "C/C", "C/A"), 
        dad = c("G/A", "T/T", "A/A"), 
        child = c("G/G", "T/T", "A/T") 
        ), stringsAsFactors = FALSE) 

現在,我們可以設置我們的功能來檢查孩子的等位基因。您必須將c(1,2,3)更改爲c(8,9,10)才能在您的數據集上工作,但它應該可以工作。這是我們將在數據框的每一行使用的函數。它將分割家族的所有基因型,將孩子與母親和父親進行比較,然後確定孩子的基因型是否與任一父母匹配。

check_child_allele <- function(x) { 
    fam <- strsplit(as.character(x[c(1, 2, 3)]), "/") 
    names(fam) <- c("mom", "dad", "child") 
    mom_query <- fam[["child"]] %in% fam[["mom"]] 
    dad_query <- fam[["child"]] %in% fam[["dad"]] 
    fam_matrix <- matrix(c(mom = mom_query, dad = dad_query), nrow = 2) 
    child_match_parents <- rowSums(fam_matrix) 
    child_geno <- ifelse(child_match_parents < 1, FALSE, TRUE) 
    return(child_geno) 
} 

檢查示例。

apply(x, 1, check_child_allele) 

##  [,1] [,2] [,3] 
## [1,] TRUE TRUE TRUE 
## [2,] TRUE TRUE FALSE 

更改數據框以表示與父母都不匹配的孩子。

y <- x 
y[2, 3] <- "A/G" # Adding a child that has no alleles in common with parents 
apply(y, 1, check_child_allele) 

##  [,1] [,2] [,3] 
## [1,] TRUE FALSE TRUE 
## [2,] TRUE FALSE FALSE 

一個側面說明,可能不相關的工作:

一件事,你可能會擔心的是,這將檢查等位基因存在於父母任何一方,但它會不檢查父母雙方是否確實可能是父母。第一個數據框中的第二組基因型是一個例子,因爲孩子是「T/T」,但母親是「C/C」。

希望有幫助!

+0

非常感謝 - 這個解決方案對我來說更好。我最終想到這樣一個事實,即這不會真正檢查父母是否是正確的父母 - 但是有沒有辦法解決這個問題? – user2726449

+0

有。如果您在函數中注意到,'fam_matrix'將是T/F值的矩陣,其中行是孩子的等位基因,列是對父母(分別爲父母和媽媽)的挑戰。 如果你在裏面添加'parents_match_child < - colSums(fam_matrix)',那會給你父母是否與孩子匹配的值。你可以用它來創建一個雙'ifelse'語句: 'child_geno < - ifelse(parents_match_child <1,FALSE,ifelse(child_match_parents <1,FALSE,TRUE))' – ZNK

1

首先,如果你發現自己一遍又一遍地做同樣的事情,寫一個函數。因此,而不是

c(sapply(strsplit(as.character(vcf_GT[,10]),"/"),function(x) x[1]))... 

寫一個小包裝:

myfun <- function(var1, var2, dat=vcf_GT) { 
    sapply(strsplit(as.character(dat[,var1], '/'), 
      function(x) x[var2]) 
} 

現在你在上面粘貼的東西變成類似:

regexpr(c(myfun(10, 1), 
      myfun(10, 2)... 

不過,我覺得還有一個更簡單的方法..

爲了解決這樣的問題(或任何種類的問題),我通常把它分解成塊。與單一的「行」開始,就像你給寫你想要什麼的一些功能(對不起,如果我已經得到了這個錯誤,但那是混亂的代碼!)...

dad = 'A/G' 
mom = 'G/A' 
kid = 'G/G' 

splt <- function(x) unlist(strsplit(x, '/')) 
comp <- function(x, y) c(x[1] %in% y, x[2] %in% y) 

comp(splt(kid), splt(dad)) 

從那裏你是一個apply從一個data.frame這樣走:

## make some data 
possible <- expand.grid(c('C', 'T', 'A', 'G'), 
         c('C', 'T', 'A', 'G')) 

gen <- function(n, pos=possible) { 
    res=possible[sample(1:nrow(possible), n, replace=TRUE),] 
    return (paste(res[,1], res[,2], sep='/')) 
} 

n <- 10 
dat <- data.frame(mom=gen(n), dad=gen(n), kid=gen(n)) 

# put both functions together 
splt_and_comp <- function(x, y) { 
    x <- splt(x) 
    y <- splt(y) 

    comp(x, y) 
} 

# you could do this with `apply` as well... 
mapply(splt_and_comp, dat$kid, dat$mom) 

FWIW,當前的代碼調用regexpr有三個參數如下。它非常好的人能發揮作用,但不可能閱讀和額外的括號遍:

first_arg <- c(sapply(strsplit(as.character(vcf_GT[,10]), "/"), 
         function(x) x[1])) 

second_arg <- (sapply(strsplit(as.character(vcf_GT[, 10]), "/"), 
         function(x) x[2])) 

third_arg <- (c(c(sapply(strsplit(as.character(vcf_GT[,9]),"/"), 
          function(x) x[1])), 
        (sapply(strsplit(as.character(vcf_GT[,9]),"/"), 
          function(x) x[2])), 
        c(sapply(strsplit(as.character(vcf_GT[,8]),"/"), 
          function(x) x[1])), 
        (sapply(strsplit(as.character(vcf_GT[,8]),"/"), 
          function(x) x[2])))) 
+0

謝謝!讓我對此有一個解釋並讓你知道。希望這可以讓我更好地瞭解我想要的作爲期望的輸出。在此期間,我其實已經感到困惑... – user2726449

相關問題