2017-05-08 75 views
0

我想有條件地使用嵌套的ifelse()語句替換一個數據框中的值與另一個數據框中的值。但是我在使用apply將它擴展到整個數據框時遇到了問題。如果可能的話,我想避免循環和非基本包。應用ifelse使用另一個data.frame的索引

第一個是六個obs的數據框。 10個字符變量:

> snp_test 
    L1 L2 L3 L4 L5 L6 L7 L8 L9 L10 
1 1 2 - 0 2 0 0 0 0 2 
2 1 0 - 0 - 1 0 - - 2 
3 - - - 0 - - 0 - - 1 
4 2 0 0 0 0 - 0 0 0 0 
5 2 0 - 0 2 - 0 0 0 1 
6 1 0 - 0 0 0 0 0 - 0 

第二個包含三列數據(字符;每個是由空格隔開的兩個字母)與每個變量:

> locus_test 
    locus gt0 gt1 gt2 
1  L1 G G A A G A 
2  L2 T T G G T G 
3  L3 A A C C A C 
4  L4 T T A A T A 
5  L5 G G C C G C 
6  L6 C C A A C A 
7  L7 T T C C T C 
8  L8 A A G G A G 
9  L9 A A G G A G 
10 L10 G G A A G A 

我想替換的值在snp_test中使用locus_test中的值。例如,當L1 == 1時,1將被替換爲locus_test $ gt1(「A A」)中的相應值。當L1 == 2時,使用gt2列中的值(「G A」)。

我可以爲每個變量分別做到這一點:

ifelse(snp_test[,1]==1,locus_test$gt1[locus_test$locus =="L1"],snp_test[,1]) 

然後我要嵌套的ifelse,使得三個不同的值被替換爲在locus_test它們相應的值,例如:

ifelse(ifelse(snp_test[,1]==1,locus_test$gt1[locus_test$locus =="L1"],snp_test[,1])==2,locus_test$gt2[locus_test$locus =="L1"],ifelse(snp_test[,1]==1,locus_test$gt1[locus_test$locus =="L1"],snp_test[,1])) 

等等......

但是當我將這個應用於snp_test的所有變量,即

apply(snp_test,2,function(x)ifelse(x==1,locus_test$gt1,x)) 

locus_test $ gt1的前六個值被用作替換值,而不是與每列相關的單個值。所以我想知道如何添加必要的索引,以便在例如snp_test的L1列中取代的值只能是與locus_test中的L1對應的三個變量之一。

換句話說,我怎麼可以指定ifelse的子集部分:

locus_test$gt1[locus_test$locus =="L1"] 
在申請

回答

0

這裏有一種方法

library(tidyverse) 
left_join(
    snp_test %>% tibble::rownames_to_column() %>% gather(locus, key, -rowname), 
    gather(locus_test, key, value, -locus) %>% mutate(key=substr(key,3,3)), 
    by = c("locus", "key") 
) %>% 
    select(-key) %>% 
    mutate(value=if_else(is.na(value),"-",value)) %>% 
    spread(locus, value) 
# rowname L1 L10 L2 L3 L4 L5 L6 L7 L8 L9 
# 1  1 AA GA TG - TT GC CC TT AA AA 
# 2  2 AA GA TT - TT - AA TT - - 
# 3  3 - AA - - TT - - TT - - 
# 4  4 GA GG TT AA TT GG - TT AA AA 
# 5  5 GA AA TT - TT GC - TT AA AA 
# 6  6 AA GG TT - TT GG CC TT AA - 
相關問題