2016-11-14 4 views
2

У меня есть один кадры данных, как показано ниже, df1 и df2:Как создать цикл с двумя семенями, если использовать три data.frames в R?

# 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) 

у меня есть третий dataframe (DF3), как:

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

Я хочу сравнить А1 и А2 df1 АА и DA df2, а затем выводят на третий df3. Моя логика такова:

  1. Если df1$zscore в df1 положителен: Я хочу увидеть, если df1$A1 == df2$DA, если да, то я хочу, чтобы положить df2$SDS в df3$SDS. Если df1$A1 == df2$AA, то я хочу поставить НЕГАТИВНО df2$SDS в df3$SDS.
  2. Если df1$zscore в df1 отрицателен: Я хочу увидеть, если df1$A2 == df2$DA, если да, то я хочу, чтобы поставить df2$SDS в df3$SDS Если df1$A2 == df2$AA, то я хочу, чтобы поставить негатив df2$SDS в df3$SDS

Конечный результат будет таким образом выглядеть следующим образом:

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

Это не тот же выход. У вас есть значения «NA», потому что ваши инструкции «if» пропускают условие. Подумайте о сценарии, когда zscore отрицательный, а A2 не равен DA, ваш скрипт остановится и вернет NA, когда он должен перейти к тестированию A2 и AA. Ваш цикл будет проверять только A2 == AA ** после ** A2 == DA TRUE, которого никогда не произойдет. –

3

Вот еще один подход. Сначала мы определяем, где zscore отрицательный. Затем выберите, какой столбец будет сопоставлен с df2. Затем определите, какой столбец df2 совпал. Строка 4 является защитой для случаев, когда между двумя кадрами данных нет соответствия. Наконец, мы возвращаем 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