Постоянное добавление к строке с учетом различных операторов if [R]
У меня запутанная проблема, и я надеюсь, что смогу объяснить это легко...
У меня есть следующие данные:
CHROM POS REF SNP INDEL
5 290 A --|T|--|-- 0
5 890 A A|T|--|G 0
7 672 A A|--|C|-- +C,+CC
9 459 G A|T|--|G -C
Я хочу создать переменную ALT, чтобы в конце концов запустить ее через VCFtools. Однако я не совсем уверен, как создать переменную, постоянно добавляя к ней, если и только если удовлетворяется определенное утверждение.
Например:
Первый столбец прост, ALT только T; однако я хочу вставить только T в столбец ALT, не добавляя "|" или же "--". Второе немного отличается, я не хочу добавлять A в переменную ALT только потому, что она видна под записью SNP, но добавляю T и G, разделенные столбцом.
По сути, я хочу добавить каждую букву в переменную ALT, только если она не равна переменной REF и не равна "-".
Я пошел дальше и разделил колонку SNP следующим образом:
m$A <- sapply(strsplit(as.character(mito$SNP),"\\|"),function(x) x[1])
m$T <- sapply(strsplit(as.character(mito$SNP),"\\|"),function(x) x[2])
m$C <- sapply(strsplit(as.character(mito$SNP),"\\|"),function(x) x[3])
m$G <- sapply(strsplit(as.character(mito$SNP),"\\|"),function(x) x[4])
Но вроде застрял отсюда. Также у меня есть проблема с "+C,+CC" и "-C"... с этими буквами буквы в столбце SNP игнорируются, но REF и ALT становятся: "A" и "AC,ACC" и "GC" и "G" соответственно. Я также разделил это:
m$indel1 <- sapply(strsplit(as.character(mito$INDEL),","),function(x) x[1])
m$indel2 <- sapply(strsplit(as.character(mito$INDEL),","),function(x) x[2])
Если это не имеет смысла; Вот то, что я хотел бы, чтобы различные варианты были:
CHROM POS REF SNP INDEL ALT
5 290 A --|T|--|-- 0 T
5 890 A A|T|--|G 0 T,G
7 672 A A|--|C|-- +C,+CC AC,ACC
9 459 GC A|T|--|G -C G
Я только включил вышеупомянутые примеры, но есть все различные комбинации этого в файле. Может ли это быть сделано в R, или это будет очень сложно.
Спасибо заранее...
Примечание 1:
Во-первых, извинения, если это не было ясно для начала в моем запросе выше. И спасибо тем, кто помог до сих пор. В соответствии с запросом переменная ALT будет изменяться для INDEL в зависимости от того, есть ли знак "-" или знак "+" перед INDEL (т.е. это не будет следовать тому же правилу, что и SNP, который будет составлять большую часть строки).
Например:
"-C" (или там, где есть знак "-"), как указано выше, REF должен стать REF+INDEL, а ALT становится REF (разделенным запятой, если необходимо):
CHROM POS REF SNP INDEL ALT 9 459 GC A|T|--|G -C G
Если есть знак "+" (будь то + C, + CC или +GGG или что-то еще), REF остается тем же, но ALT становится REF+INDEL (разделяется запятой, если это необходимо):
CHROM POS REF SNP INDEL ALT 7 672 A A|--|C|-- +C,+CC AC,ACC 9 987 T --|T|C|-- +GGG TGGG
3 ответа
Я попробовал что-то немного наивное - и, возможно, не настолько эффективное - для произвольной экстраполяции, которую я сделал на вашем фрейме данных. Конечно, если я ошибаюсь, это можно изменить. Во всяком случае, я надеюсь, что это полезно.
#> DF
# CHROM POS REF SNP INDEL
#1 5 290 A --|T|--|-- 0
#2 5 890 A A|T|--|G 0
#3 7 672 A A|--|C|-- +C,+CC
#4 9 459 G A|T|--|G -C
#5 3 554 T A|T|--|G -GG,-A
#6 9 987 T --|T|C|-- +GGG
#7 21 214 G A|T|--|G 0
#8 1 145 G G|--|--|G 0
#9 3 554 T,C A|T|--|G -GG,-A
#10 7 672 A,T A|--|C|-- +C,+CC
И то, что я думал, будет решением:
ff = function(xrow) {
ref = as.character(xrow[3])
snp = as.character(xrow[4])
indel = as.character(xrow[5])
if(indel == "0") {
alt = gsub(paste(ref, "|\\||--", sep = ""), "", snp)
if(nchar(alt) > 1)
alt = paste(strsplit(alt, "", fixed = T)[[1]], collapse = ",")
}
else {
indels = strsplit(indel, ",", fixed = T)[[1]]
if(grepl("-", indels[1], fixed = T)) {
alt = ref
ref = paste0(strsplit(ref, ",", fixed = T)[[1]],
gsub("-", "", indels, fixed = T), collapse = ",")
}
if(grepl("+", indels[1], fixed = T)) {
alt = paste0(strsplit(ref, ",", fixed = T)[[1]],
gsub("+", "", indels, fixed = T), collapse = ",")
}
}
return(cbind(CHROM = xrow[1], POS = xrow[2], REF = ref,
SNP = snp, INDEL = indel, ALT = alt))
}
as.data.frame(t(apply(DF, 1, ff)))
# V1 V2 V3 V4 V5 V6
#1 5 290 A --|T|--|-- 0 T
#2 5 890 A A|T|--|G 0 T,G
#3 7 672 A A|--|C|-- +C,+CC AC,ACC
#4 9 459 GC A|T|--|G -C G
#5 3 554 TGG,TA A|T|--|G -GG,-A T
#6 9 987 T --|T|C|-- +GGG TGGG
#7 21 214 G A|T|--|G 0 A,T
#8 1 145 G G|--|--|G 0
#9 3 554 TGG,CA A|T|--|G -GG,-A T,C
#10 7 672 A,T A|--|C|-- +C,+CC AC,TCC
DF
:
structure(list(CHROM = c("5", "5", "7", "9", "3", "9", "21",
"1", "3", "7"), POS = c("290", "890", "672", "459", "554", "987",
"214", "145", "554", "672"), REF = c("A", "A", "A", "G", "T",
"T", "G", "G", "T,C", "A,T"), SNP = c("--|T|--|--", "A|T|--|G",
"A|--|C|--", "A|T|--|G", "A|T|--|G", "--|T|C|--", "A|T|--|G",
"G|--|--|G", "A|T|--|G", "A|--|C|--"), INDEL = c("0", "0", "+C,+CC",
"-C", "-GG,-A", "+GGG", "0", "0", "-GG,-A", "+C,+CC")), .Names = c("CHROM",
"POS", "REF", "SNP", "INDEL"), row.names = c(NA, 10L), class = "data.frame")
Для первой части логики, что-то вроде этого работает:
mito <- read.table(text="CHROM POS REF SNP INDEL
5 290 A --|T|--|-- 0
5 890 A A|T|--|G 0
7 672 A A|--|C|-- +C,+CC
9 459 G A|T|--|G -C",header=TRUE,stringsAsFactors=FALSE)
msgstr " добавлять каждую букву в переменную ALT, только если она не равна переменной REF и не равна '-' ".
SNPlist <- strsplit(mito$SNP,"\\|")
output <- Map(function(x,y) x[x!=y & x!="--"] , SNPlist, mito$REF)
mito$alt <- sapply(output,paste,collapse=",")
mito
# CHROM POS REF SNP INDEL alt
#1 5 290 A --|T|--|-- 0 T
#2 5 890 A A|T|--|G 0 T,G
#3 7 672 A A|--|C|-- +C,+CC C
#4 9 459 G A|T|--|G -C A,T
Вы можете попробовать это:
library(stringr)
snp <- str_extract_all(string = df$SNP, pattern = "[[:alpha:]]")
snp2 <- mapply(FUN = function(x, y) x[x != y], x = snp, y = df$REF)
df$ALT <- lapply(snp2, function(x) paste(x, collapse = ","))
df$ALT[df$INDEL == "+C,+CC"] <- "AC,ACC"
df$ALT[df$INDEL == "-C"] <- "G"
df
# CHROM POS REF SNP INDEL ALT
# 1 5 290 A --|T|--|-- 0 T
# 2 5 890 A A|T|--|G 0 T,G
# 3 7 672 A A|--|C|-- +C,+CC AC,ACC
# 4 9 459 G A|T|--|G -C G