|
1 | | -.feature_list_to_df <- function(x) { |
2 | | - # dat <- data.frame( |
3 | | - # index = numeric(), |
4 | | - # name = character(), |
5 | | - # type = character(), |
6 | | - # start = numeric(), |
7 | | - # end = numeric(), |
8 | | - # direction = numeric() |
9 | | - # ) |
| 1 | +.feature_list_to_df <- function(x, bp = NULL, ...) { |
10 | 2 |
|
11 | 3 | feats <- lapply(seq(length(x)), \(i) { |
12 | 4 | feat <- x[[i]] |
|
22 | 14 | }) |
23 | 15 |
|
24 | 16 | dat <- do.call(rbind, feats) |
25 | | - # } |
26 | 17 |
|
27 | 18 | # turn certain features in to numeric columns |
28 | 19 | dat$start <- as.numeric(dat$start) |
29 | 20 | dat$end <- as.numeric(dat$end) |
30 | 21 | dat$direction <- as.numeric(dat$direction) |
31 | 22 |
|
| 23 | + over_origin <- dat$start > dat$end & dat$direction == 1 |
| 24 | + |
| 25 | + if (any(over_origin)) { |
| 26 | + if (is.null(bp)) { |
| 27 | + bp <- max(c(dat$start, dat$end)) |
| 28 | + } |
| 29 | + |
| 30 | + # For origin-spanning features like join(4891..5096,1..751): |
| 31 | + # - We need to offset the coordinate system so this becomes continuous |
| 32 | + # - The offset should be chosen so that the feature becomes [new_start..new_end] |
| 33 | + # - All other features get shifted by the same offset |
| 34 | + |
| 35 | + # Find the origin-spanning feature with the smallest end coordinate |
| 36 | + # This determines our offset |
| 37 | + min_end <- min(dat$end[over_origin]) |
| 38 | + offset <- min_end |
| 39 | + |
| 40 | + # Apply offset to all coordinates |
| 41 | + dat$start <- dat$start - offset |
| 42 | + dat$end <- dat$end - offset |
| 43 | + |
| 44 | + # For origin-spanning features, calculate the correct end position |
| 45 | + # Original: join(4891..5096, 1..751) with bp=5096 |
| 46 | + # After offset by 751: start=4140, end=0 |
| 47 | + # Correct end should be: start + ((5096-4891+1) + 751 - 1) = 4140 + 956 = 5096 |
| 48 | + for (i in which(over_origin)) { |
| 49 | + original_start <- dat$start[i] + offset # Restore original start |
| 50 | + original_end <- dat$end[i] + offset # Restore original end |
| 51 | + |
| 52 | + # Calculate total feature length: (bp - start + 1) + end |
| 53 | + part1_length <- bp - original_start + 1 # From start to end of plasmid |
| 54 | + part2_length <- original_end # From beginning to end position |
| 55 | + total_length <- part1_length + part2_length |
| 56 | + |
| 57 | + # Set the new end position |
| 58 | + dat$end[i] <- dat$start[i] + total_length - 1 |
| 59 | + } |
| 60 | + |
| 61 | + # Handle any negative coordinates by wrapping them around |
| 62 | + negative_coords <- dat$start < 0 | dat$end < 0 |
| 63 | + dat$start[negative_coords & dat$start < 0] <- |
| 64 | + dat$start[negative_coords & dat$start < 0] + bp |
| 65 | + dat$end[negative_coords & dat$end < 0] <- |
| 66 | + dat$end[negative_coords & dat$end < 0] + bp |
| 67 | + } |
32 | 68 |
|
33 | 69 | # only return features where a start was successfully parsed |
34 | 70 | # dat[!is.na(dat$start), ] |
|
46 | 82 | #' @rdname as.data.frame.plasmid |
47 | 83 | #' @export |
48 | 84 | as.data.frame.plasmid <- function(x, row.names, optional, ...) { |
49 | | - .feature_list_to_df(x$features) |
| 85 | + .feature_list_to_df(x$features, bp = x$length) |
50 | 86 | } |
0 commit comments