基于区间显著重叠规则处理基因组区间输入文件的技术需求
Solution in R
Let's walk through how to generate your desired output by breaking the problem into clear, reproducible steps:
# Load your input data input <- structure(list(CT1 = structure(1:3, .Label = c("chr1:200-400", "chr1:800-970", "chr2:300-700"), class = "factor"), CT2 = structure(1:3, .Label = c("chr1:250-450", "chr2:200-500", "chr2:600-1000"), class = "factor"), CT3 = structure(1:3, .Label = c("chr1:400-800", "chr1:700-870", "chr2:700-1400"), class = "factor")), .Names = c("CT1", "CT2", "CT3"), class = "data.frame", row.names = c(NA, -3L)) # Helper function to split interval strings into usable components parse_interval <- function(interval_str) { parts <- strsplit(interval_str, ":|-")[[1]] list( chr = parts[1], start = as.integer(parts[2]), end = as.integer(parts[3]), length = as.integer(parts[3]) - as.integer(parts[2]) ) } # Preprocess all columns into parsed interval lists parsed_columns <- lapply(input, function(col) { lapply(as.character(col), parse_interval) }) # Function to check if an interval qualifies for a column (present or significant overlap) check_column_match <- function(interval_str, original_col, parsed_col) { # First check if interval exists directly in the column if (interval_str %in% original_col) { return(1L) } # Parse the target interval for overlap calculations target <- parse_interval(interval_str) # Check each interval in the column for significant overlap for (int in parsed_col) { # Skip if chromosomes don't match (no overlap possible) if (target$chr != int$chr) next # Calculate overlap length overlap_start <- max(target$start, int$start) overlap_end <- min(target$end, int$end) overlap_len <- max(0L, overlap_end - overlap_start) if (overlap_len == 0L) next # Check if overlap meets 50% threshold for either interval if (overlap_len >= 0.5 * target$length || overlap_len >= 0.5 * int$length) { return(1L) } } # No match or significant overlap found return(0L) } # Collect all unique intervals in the order of CT1 -> CT2 -> CT3 all_intervals <- unique(c(as.character(input$CT1), as.character(input$CT2), as.character(input$CT3))) # Build the final output data frame output <- data.frame( CT1 = sapply(all_intervals, check_column_match, original_col = as.character(input$CT1), parsed_col = parsed_columns$CT1), CT2 = sapply(all_intervals, check_column_match, original_col = as.character(input$CT2), parsed_col = parsed_columns$CT2), CT3 = sapply(all_intervals, check_column_match, original_col = as.character(input$CT3), parsed_col = parsed_columns$CT3), row.names = all_intervals, stringsAsFactors = FALSE ) # View the result print(output)
Expected Output
Running this code will produce exactly the format you requested:
CT1 CT2 CT3 chr1:200-400 1 1 0 chr1:800-970 1 0 0 chr2:300-700 1 1 0 chr1:250-450 1 1 0 chr2:200-500 1 1 0 chr2:600-1000 0 1 1 chr1:400-800 0 0 1 chr1:700-870 0 1 1 chr2:700-1400 0 1 1
Key Notes
- Interval Parsing: The
parse_intervalfunction breaks down each interval string into chromosome, start/end positions, and pre-calculates length for efficient overlap checks. - Overlap Logic: We first check for direct presence in the column, then calculate overlap with every interval in the column to see if it meets the 50% threshold (relative to either the target interval or the column interval).
- Order Preservation: The
all_intervalsvector maintains the order of first occurrence (CT1 entries first, then CT2, then CT3) to match your desired row order.
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

