2017-08-14 124 views
0

我實際上正在處理基因組數據,並且我有一個數據框,我將向您顯示前三行(請參閱下表):根據另一列中的行信息,在一列中替換不同的值

Chrom | POS |  ID  | REF | ALT | HapA | HapB | 
---------------------------------------------------------- 
22 | 16495833 | rs116911124 | A | C | 1 | 0 | 
22 | 19873357 | rs116378360 | T | A | 0 | 1 | 
22 | 21416404 | rs117982183 | T | T | 0 | . | 

所以,我想替換「0」,「1」和「。」的值。根據數據幀中每行的REF和ALT列從「HapA」和「HapB」列中選擇。例如:

a)對於第一行,我想要更改ALT列中「C」的HapA列中的「1」以及中的「A」值的HapB列中的「0」 b)對於第二行,「REF」欄中的「T」變爲「0」,「ALT」欄中的「A」變爲「1」。

c)最後,爲「。」將其更改爲「不適用」

我認爲這可以使用「if else」或data.table來實現。

非常感謝。

+0

它是否總是相同的規則0將被'REF'列和1替換爲'ALT'列(並且由NA)? –

+0

所以'HapA'和'HapB'都是字符列?它們不是數字或整數,因爲'.'對於這些不是有效的值。 –

+0

@SRivero嗨,是的這是總是相同的規則,0將被替換爲REF列和1 ALT列 –

回答

0

這是一個有點不清楚你想要什麼準確,因爲你沒有指定應該發生什麼0HapA列的第三行中,但考慮到你說的,這是一個dplyr解決方案:

library(dplyr) 

df <- read.table(text = " 
'Chrom'  'POS'  'ID'  'REF' 'ALT' 'HapA' 'HapB' 
22  16495833 'rs116911124' 'A'  'C'  1  0 
22  19873357 'rs116378360' 'T'  'A'  0  1 
22  21416404 'rs117982183' 'T'  'T'  0  .", header = T, stringsAsFactors = F) 

df %>% 
    mutate(HapA = ifelse(HapA == 1, ALT, ifelse(HapA == 0, REF, NA)), 
     HapB = ifelse(HapB == 1, ALT, ifelse(HapB == 0, REF, NA))) 

## Chrom  POS   ID REF ALT HapA HapB 
## 1 22 16495833 rs116911124 A C C A 
## 2 22 19873357 rs116378360 T A T A 
## 3 22 21416404 rs117982183 T T T <NA> 
+0

您好,非常感謝您的回答,它完全適用於我的數據... –

0

我認爲if_else(),recode()case_when()都可以爲此工作。在這裏,我試圖用mutate_at()將函數應用於HapA和HapB。如果這些列中的一個值不等於1,0,或。那麼該函數應該將該值作爲字符串返回。

mutate_at(df, vars(HapA, HapB), 
    function(x) {case_when(x == 1 ~ .$ALT, 
        x == 0 ~ .$REF, 
        x == . ~ NA_character_, 
        TRUE ~ as.character(x)) }) 
0

有沒有一個真正的問題,但我會猜它是什麼:

我怎麼能代替的HapA和值210遵循以下規則:

  1. 如果"0",則替換爲值REF
  2. 如果"1",則用值​​替換。
  3. 如果".",則替換爲NA

請注意,我也假設HapAHapB是字符列,因爲.不能是一個數值。

如果這是正確的解釋,沒有必要使用花哨的技巧。這是一個「if-else」問題。這是一個使用data.table的解決方案,我認爲這在基因組分析中很常見。首先,我將創建示例數據集:

library(data.table) 

dt <- fread(
    header = TRUE, 
    colClasses = c(
    Chrom = "character", 
    POS = "integer", 
    ID = "character", 
    REF = "character", 
    ALT = "character", 
    HapA = "character", 
    HapB = "character" 
), 
    input = " 
Chrom POS  ID    REF  ALT  HapA HapB 
22  16495833 'rs116911124' 'A'  'C'  1  0 
22  19873357 'rs116378360' 'T'  'A'  0  1 
22  21416404 'rs117982183' 'T'  'T'  0  ." 
) 
dt 
# Chrom  POS   ID REF ALT HapA HapB 
# 1: 22 16495833 'rs116911124' 'A' 'C' 1 0 
# 2: 22 19873357 'rs116378360' 'T' 'A' 0 1 
# 3: 22 21416404 'rs117982183' 'T' 'T' 0 . 

這是很長的一部分。這是簡短的部分。

dt[HapA == "0", HapA := REF] 
dt[HapA == "1", HapA := ALT] 
dt[HapA == ".", HapA := NA] 
dt[HapB == "0", HapB := REF] 
dt[HapB == "1", HapB := ALT] 
dt[HapB == ".", HapB := NA] 
dt 
# Chrom  POS   ID REF ALT HapA HapB 
# 1: 22 16495833 'rs116911124' 'A' 'C' 'C' 'A' 
# 2: 22 19873357 'rs116378360' 'T' 'A' 'T' 'A' 
# 3: 22 21416404 'rs117982183' 'T' 'T' 'T' NA 

強烈建議以簡單的方式寫了這一點,像上面。它很短,幾乎沒有重複,並且一目瞭然便於理解。但是,如果您想將其推廣到很多列,那就需要編寫大量的重複行。所以這裏是一個循環版本:

replaced_columns <- c("HapA", "HapB") # Switch these out for any 
source_columns <- c("REF", "ALT") # number of columns 

for (rr in replaced_columns) { 
    for (source_i in seq_along(source_columns)) { 
    target_rows <- which(dt[[rr]] == source_i - 1) 
    dt[ 
     target_rows, 
     (rr) := .SD, 
     .SDcols = source_columns[source_i] 
    ] 
    } 
} 

dt 
# Chrom  POS   ID REF ALT HapA HapB 
# 1: 22 16495833 'rs116911124' 'A' 'C' 'C' 'A' 
# 2: 22 19873357 'rs116378360' 'T' 'A' 'T' 'A' 
# 3: 22 21416404 'rs117982183' 'T' 'T' 'T' . 
相關問題