Fusionar por rango en R – Aplicar bucles

Publiqué una pregunta aquí: Combinación de rango combinado en R sobre la fusión de dos archivos en función de un número en un archivo que cae en un rango en el segundo archivo. Hasta ahora, no he tenido éxito en unir código para lograr esto. El problema que estoy teniendo es que el código que estoy usando compara los archivos línea por línea. Esto es un problema porque 1.) Un archivo es mucho más largo que el otro archivo, y 2.) Necesito las líneas en el archivo más corto para escanear a través de cada par de rango en el archivo más largo, no solo el rango en la misma fila .

He estado trabajando con las funciones publicadas en la pregunta original, y creo que debería haber una forma de aplicarlo a un ciclo más general que compare cada línea en el primer archivo con cada línea en el segundo archivo, pero no lo he hecho. t lo descubrió todavía. Si alguien tiene alguna sugerencia, la agradecería.

**** EDITADO.

La naturaleza de los datos es la siguiente: cada rango no es necesariamente único, aunque la mayoría sí lo es. Tampoco son del mismo tamaño, y algunos caen completamente dentro de otros. findInterval por findInterval tanto produce un error, porque los rangos no pueden ser ordenados para caer en orden “no descendente”.

Aquí están las primeras 6 líneas de cada dataframe:

 file1test <- data.frame(SNP=c("rs2343", "rs211", "rs754", "rs854", "rs343", "rs626"), BP=c(860269, 369640, 861822, 367934, 706940, 717244)) file2 <- data.frame(Gene=c("E613", "E92", "E49", "E3543", "E11", "E233"), BP_start=c(367640, 621059, 721320, 860260, 861322, 879584), BP_end = c(368634, 622053, 722513, 879955, 879533, 894689)) 

Entonces, como puede ver, el rango en la 5ª línea se encuentra dentro del rango en la 4ª línea, y dos SNP del primer archivo caen dentro del rango en la 4ª línea, pero solo uno cae dentro del rango en la segunda línea.

El primer archivo, que contiene los SNP, tiene solo ~ 400 líneas. Sin embargo, el segundo archivo, que contiene los rangos, tiene aproximadamente 20K. Lo que me gustaría producir como salida es un dataframe que contiene las líneas del primer archivo (los SNP) con BP que caen dentro del rango de BP en el segundo archivo. Si un SNP cae en dos rangos, aparecería dos veces, etc.

    El paquete GenomicRanges en Bioconductor está diseñado para este tipo de operación. Lea sus datos con, por ejemplo, read.delim para que

     con <- textConnection("SNP BP rs064 12292 rs319 345367 rs285 700042") snps <- read.delim(con, head=TRUE, sep="") con <- textConnection("Gene BP_start BP_end E613 345344 363401 E92 694501 705408 E49 362370 368340") ## missing trailing digit on BP_end?? genes <- read.delim(con, head=TRUE, sep="") 

    luego crea 'IRanges' de cada

     library(IRanges) isnps <- with(snps, IRanges(BP, width=1, names=SNP)) igenes <- with(genes, IRanges(BP_start, BP_end, names=Gene) 

    (preste atención a los sistemas de coordenadas, IRanges espera que el inicio y el final se incluyan en el rango; también, end> ​​= start espera para rangos de ancho 0 cuando end = start - 1). Luego encuentre los SNP ('consulta' en la terminología de IRanges) que se superponen a los genes ('sujeto')

     olaps <- findOverlaps(isnps, igenes) 

    dos de los SNP se superponen

     > queryHits(olaps) [1] 2 3 

    y se superponen con los genes primero y segundo

     > subjectHits(olaps) [1] 1 2 

    Si una consulta se superpone a múltiples genes, se habría repetido en queryHits (y viceversa). A continuación, podría fusionar sus marcos de datos como

     > cbind(snps[queryHits(olaps),], genes[subjectHits(olaps),]) SNP BP Gene BP_start BP_end 2 rs319 345367 E613 345344 363401 3 rs285 700042 E92 694501 705408 

    Por lo general, los genes y los SNP tienen información cromosómica y de cadena ('+', '-' o '*' para indicar que la cadena no es importante), y usted desearía superponerse en el contexto de estos; en lugar de crear instancias de 'IRanges', crearías 'GRanges' (rangos genómicos) y la subsiguiente contabilidad se ocuparía de ti

     library(GenomicRanges) isnps <- with(snps, GRanges("chrA", IRanges(BP, width=1, names=SNP), "*") igenes <- with(genes, GRanges("chrA", IRanges(BP_start, BP_end, names=Gene), "+")) 

    Creo que lo que estás pidiendo es una conditional join . Son fáciles en SQL, y el paquete sqldf facilita la consulta de marcos de datos en R mediante SQL.

    Solo elija una versión dependiendo de cómo quiera que se manejen los SNP sin igual.

    Versión de unión interna:

     > sqldf("select * from file1test f1 inner join file2 f2 + on (f1.BP > f2.BP_start and f1.BP<= f2.BP_end) ") 

    Salida:

      SNP BP Gene BP_start BP_end 1 rs2343 860269 E3543 860260 879955 2 rs754 861822 E3543 860260 879955 3 rs754 861822 E11 861322 879533 4 rs854 367934 E613 367640 368634 > 

    Left Unir versión:

     > sqldf("select * from file1test f1 left join file2 f2 + on (f1.BP > f2.BP_start and f1.BP<= f2.BP_end) ") 

    Salida:

      SNP BP Gene BP_start BP_end 1 rs2343 860269 E3543 860260 879955 2 rs211 369640  NA NA 3 rs754 861822 E3543 860260 879955 4 rs754 861822 E11 861322 879533 5 rs854 367934 E613 367640 368634 6 rs343 706940  NA NA 7 rs626 717244  NA NA > 

    Tenga en cuenta que es posible que desee tener cuidado donde coloca el = si importa qué grupo un BP caerá en el caso donde un BP coincide exactamente con BP_start o BP_end.