Вычисление общей суммы отрезков линий, перекрывающихся на линии - PullRequest
0 голосов
/ 28 сентября 2018

Я пытаюсь подсчитать общую сумму перекрывающихся отрезков в одной строке.С линией A сегменты разделены, поэтому вычислить довольно просто.Тем не менее, с линиями B и C, есть перекрывающиеся отрезки, так что это сложнее.Мне нужно как-то исключить части предыдущих строк, которые уже являются частью общей суммы.

data = read.table(text="
    line    left_line   right_line  small_line  left_small_line right_small_line
    A   100 120 101 91  111
    A   100 120 129 119 139
    B   70  90  63  53  73
    B   70  90  70  60  80
    B   70  90  75  65  85
    C   20  40  11  1   21
    C   20  40  34  24  44
    C   20  40  45  35  55", header=TRUE)

Это должен быть ожидаемый результат.

result = read.table(text="
    total_overlapping
A   0.6
B   0.75
C   0.85", header=TRUE)

РЕДАКТИРОВАТЬ: Добавлена ​​картинка, чтобы лучше проиллюстрировать то, что я пытаюсь выяснить.Есть 3 разных изображения линий (сплошная красная линия) с перекрывающимися сегментами (пунктирные линии).Цель состоит в том, чтобы выяснить, сколько пунктирных линий покрывают / перекрывают друг друга.

Линия A
Line A:

Линия B Line B: Строка C Lince C:

1 Ответ

0 голосов
/ 28 сентября 2018

Если я правильно понимаю, переменная small_line здесь не имеет значения.Остальные столбцы можно использовать для получения суммы перекрывающихся сегментов:

Шаг 1 .Получите начальную и конечную точки для перекрытия каждого сегмента с соответствующей линией:

library(dplyr)

data1 <- data %>%
  rowwise() %>%
  mutate(overlap.start = max(left_line, left_small_line),
         overlap.end = min(right_line, right_small_line)) %>%
  ungroup() %>%
  select(line, overlap.start, overlap.end)

> data1
# A tibble: 8 x 3
  line  overlap.start overlap.end
  <fct>         <int>       <int>
1 A               100         111
2 A               119         120
3 B                70          73
4 B                70          80
5 B                70          85
6 C                20          21
7 C                24          40
8 C                35          40

Шаг 2 .В строках, соответствующих каждой строке, сортируйте перекрытия по порядку.считать это новым перекрывающимся разделом, если это первое перекрытие, ИЛИ предыдущее перекрытие заканчивается до его начала.Маркируйте каждую новую секцию перекрытия:

data2 <- data1 %>%
  arrange(line, overlap.start, overlap.end) %>%
  group_by(line) %>%
  mutate(new.section = is.na(lag(overlap.end)) | 
           lag(overlap.end) <= overlap.start) %>%
  mutate(section.number = cumsum(new.section)) %>%
  ungroup()

> data2
# A tibble: 8 x 5
  line  overlap.start overlap.end new.section section.number
  <fct>         <int>       <int> <lgl>                <int>
1 A               100         111 TRUE                     1
2 A               119         120 TRUE                     2
3 B                70          73 TRUE                     1
4 B                70          80 FALSE                    1
5 B                70          85 FALSE                    1
6 C                20          21 TRUE                     1
7 C                24          40 TRUE                     2
8 C                35          40 FALSE                    2

Шаг 3 .В каждом перекрывающемся разделе выберите самую раннюю начальную точку и самую последнюю конечную точку.Рассчитайте длину каждого перекрытия:

data3 <- data2 %>%
  group_by(line, section.number) %>%
  summarise(overlap.start = min(overlap.start),
            overlap.end = max(overlap.end)) %>%
  ungroup() %>%
  mutate(overlap = overlap.end - overlap.start)

> data3
# A tibble: 5 x 5
  line  section.number overlap.start overlap.end overlap
  <fct>          <int>         <dbl>       <dbl>   <dbl>
1 A                  1           100         111      11
2 A                  2           119         120       1
3 B                  1            70          85      15
4 C                  1            20          21       1
5 C                  2            24          40      16

Шаг 4 .Суммируйте длину перекрытий для каждой строки:

data4 <- data3 %>%
  group_by(line) %>%
  summarise(overlap = sum(overlap)) %>%
  ungroup()

> data4
# A tibble: 3 x 2
  line  overlap
  <fct>   <dbl>
1 A          12
2 B          15
3 C          17

Теперь ожидаемый результат показывает ожидаемый процент перекрытий в каждой строке, а не сумму.Если это то, что вы ищете, вы можете добавить длину для каждой строки к data4 и рассчитать соответственно:

data5 <- data4 %>%
  left_join(data %>% 
              select(line, left_line, right_line) %>%
              unique() %>% 
              mutate(length = right_line - left_line) %>%
              select(line, length),
            by = "line") %>%
  mutate(overlap.percentage = overlap / length)

> data5
# A tibble: 3 x 4
  line  overlap length overlap.percentage
  <fct>   <dbl>  <int>              <dbl>
1 A          12     20               0.6 
2 B          15     20               0.75
3 C          17     20               0.85
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...