2016-11-14 3 views
2

私は、以下のようにdf1df2を1つのデータフレームを持っている:私はAAにDF1のA1とA2を比較したいRで3つのdata.framesを使用して二重にシードされた "if"ループを作成する方法は?

Input_SNP SDS 
1:3344877 NA 
1:3345145 NA 
1:3345216 NA 
1:3345705 NA 
1:3346348 NA 
1:3346403 NA 

と:私はのような第三データフレーム(DF3)を持っている

# data 
df1 <- read.table(text = " 
    SNP CHR   BP A1  A2  zscore  P CEUmaf LOC 
rs58043752  1  3344877 A  G  0.289 0.7726 . 1:3344877 
rs2483242  1  3345145 A  T  0.393 0.6946 . 1:3345145 
rs1572039  1  3345216 T  C  0.443 0.658 . 1:3345216 
rs1537407  1  3345705 T  C  -0.289 0.7726 . 1:3345705 
rs2493277  1  3346348 C  G  -1.552 0.1207 0.09167 1:3346348 
rs11583353  1  3346403 C  T  -0.414 0.6786 0.875 1:3346403", 
        header = TRUE, stringsAsFactors = FALSE) 
df2 <- read.table(text = " 
    CHR   POS   ID  AA  DA   DAF    SDS    LOC 
1  3344877 rs58043752  G  A  0.1095 0.80517243505521  1:3344877 
1  3345145 rs2483242  T  A  0.5746 0.741513997303754  1:3345145 
1  3345216 rs1572039  T  C  0.0784 0.130228249846394  1:3345216 
1  3345705 rs1537407  C  T  0.798 0.275710355505832  1:3345705 
1  3346348 rs2493277  G  C  0.5737 0.283452115383779  1:3346348 
1  3346403 rs11583353  C  T  0.2238 -0.0246952604330743  1:3346403", 
        header = TRUE, stringsAsFactors = FALSE) 

DAをdf2とし、第3のdf3まで出力する。次のように私のロジックは次のとおりです。

  1. df1df1$zscoreが正の場合: 私はdf1$A1 == df2$DA場合ははい、私はdf3$SDSdf2$SDSを置きたい場合は、見てみたいです。 df1$A1 == df2$AAの場合、df2$SDSのNEGATIVEをdf3$SDSに入力します。
  2. df1df1$zscoreが負の場合: はい、私はその後、私はdf3$SDS
df2$SDSのNEGATIVEを置きたい、 df1$A2 == df2$AA場合 df3$SDSdf2$SDSを置きたい場合、私は、 df1$A2 == df2$DAかどうかを確認したいです

最終的な出力は次のようになります:

Input_SNP  SDS 
    1:3344877 0.805 
    1:3345145 0.742 
    1:3345216 -0.130 
    1:3345705 -0.276 
    1:3346348 -0.283 
    1:3346403 -0.025 
+0

あなたは 'dput()'とデータサンプルを投稿してくださいもらえますか? df1とdf2を条件と比較するループを作成してみませんか?何か不足していますか? – nevrome

+1

"SNP CHR BP"列でマージを使用し、ロジックを使用してフィルタリングします。 – zx8754

+1

[データフレーム(内部、外部、左、右)を結合(マージ)する方法]の可能な複製?](http://stackoverflow.com/questions/1299871)? – zx8754

答えて

1

私は確かに高速なソリューションがありますが、単純なループは利点がありますかなり話している。そして、それは簡単に調整することができます。

df1 <- data.frame(
    BP = 1:6, 
    A1 = c("A", "A", "T", "T", "C", "C"), 
    A2= c("G", "T", "C", "C", "G", "T"), 
    zscore = runif(6, min = -1, max = 1), 
    stringsAsFactors = FALSE 
) 

df2 <- data.frame(
    CHR = 1:6, 
    AA = c("G", "T", "T", "C", "G", "C"), 
    DA = c("A", "A", "C", "T", "C", "T"), 
    SDS = runif(6), 
    stringsAsFactors = FALSE 
) 

df3 <- data.frame(SDS = rep(NA, nrow(df1))) 

for (i in 1:nrow(df1)) { 
    if (df1$zscore[i] >= 0) { 
    if (df1$A1[i] == df2$DA[i]) { 
     df3$SDS[i] <- df2$SDS[i] 
    } else if (df1$A1[i] == df2$AA[i]) { 
     df3$SDS[i] <- -df2$SDS[i] 
    } 
    } else if (df1$zscore[i] < 0) { 
    if (df1$A2[i] == df2$DA[i]) { 
     df3$SDS[i] <- df2$SDS[i] 
    } else if (df1$A2[i] == df2$AA[i]) { 
     df3$SDS[i] <- -df2$SDS[i] 
    } 
    } 
} 

df3 
+2

出力が正しくありません。ループのロジックと結果を再確認してください。 –

+0

@PierreLafortune問題を再現できません。サンプルデータのソリューションと同じ結果が得られます。何が間違っているのか教えてください。 – nevrome

+1

同じ出力ではありません。あなたの 'if'ステートメントは条件をスキップするので、あなたは 'NA'値を持っています。 zscoreが負でA2がDAと等しくないシナリオを考えると、スクリプトはA2とAAをテストするために移動する必要があるときに停止し、NAを返します。あなたのループは** A2 == AAの後にのみA2 == AA **をテストします。 –

3

これは別のアプローチです。最初に、zscoreが負の値であるかどうかを判断します。次に、df2に一致する列を選択します。次に、一致したdf2列を特定します。行4は、2つのデータフレームが一致しない場合の保護手段です。最後に、条件に基づいて正または負の数値をSDSに返します。

私たちは、マージすることができ
coll <- (df1$zscore < 0) + 1L 
indx1 <- df1[c("A1","A2")][cbind(1:nrow(df1),coll)] 
matches <- max.col((xx=indx1 == df2[c("DA","AA")])) 
is.na(matches) <- rowSums(xx) == 0L 
df3$SDS <- df2$SDS * ifelse(matches == 1,1,-1) 
df3 
# Input_SNP   SDS 
# 1 1:3344877 0.80517244 
# 2 1:3345145 0.74151400 
# 3 1:3345216 -0.13022825 
# 4 1:3345705 -0.27571036 
# 5 1:3346348 -0.28345212 
# 6 1:3346403 -0.02469526 
3

、SDSの後、フリップ記号:

# merge 
res <- merge(df1[, 1:6], df2[, c(1:5, 7)], 
       by.x = c("CHR", "BP", "SNP"), 
       by.y = c("CHR", "POS", "ID")) 

# make Input_SNP id column: 
res$Input_SNP <- paste(res$CHR, res$BP, sep = ":") 

# then flip effect based on sign and allele match 
res$SDS <- ifelse(res$zscore > 0 & res$A1 == res$DA, res$SDS, 
        ifelse(res$zscore > 0 & res$A1 == res$AA, res$SDS * -1, 
         ifelse(res$zscore < 0 & res$A2 == res$DA, res$SDS, 
           ifelse(res$zscore < 0 & res$A2 == res$AA, res$SDS * -1, NA)))) 

# subset required columns 
res <- res[, c("Input_SNP", "SDS")] 
res 
# Input_SNP   SDS 
# 1 1:3344877 0.80517244 
# 2 1:3345145 0.74151400 
# 3 1:3345216 -0.13022825 
# 4 1:3345705 -0.27571036 
# 5 1:3346348 -0.28345212 
# 6 1:3346403 -0.02469526 
関連する問題