Home > Blockchain >  Find if intervals share overlap
Find if intervals share overlap

Time:08-10

Is there a simple way to find if an interval of two numbers is overlapping with an interval of two other numbers? Let's say I estimated min - max of a dose which I would like to compare to the actual min - max of a dose. Something like this:

   # A tibble: 5 × 5
     ID Estimate_Min Estimate_Max Dose_Min Dose_Max
  <dbl>        <dbl>        <dbl>    <dbl>    <dbl>
1     1         18             25        7       14
2     2         15             22       10       13
3     3          3              8        4        5
4     4         11             12       18       20
5     5          0.5           18        6       12

Is the estimated dose overlapping with the actual dose? And I would like to get:

 # A tibble: 5 × 6
     ID Estimate_Min Estimate_Max Dose_Min Dose_Max Overlap
  <dbl>        <dbl>        <dbl>    <dbl>    <dbl> <chr>  
1     1         18             25        7       14 FALSE  
2     2         15             22       10       13 FALSE  
3     3          3              8        4        5 TRUE   
4     4         11             12       18       20 FALSE  
5     5          0.5           18        6       12 TRUE   

Or better yet:

# A tibble: 5 × 6
     ID Estimate_Min Estimate_Max Dose_Min Dose_Max Overlap
  <dbl>        <dbl>        <dbl>    <dbl>    <dbl> <chr>  
1     1         18             25        7       14 OVER   
2     2         15             22       10       13 OVER   
3     3          3              8        4        5 IN     
4     4         11             12       18       20 BELLOW 
5     5          0.5           18        6       12 IN     

Where "IN" would mean that the estimated dose is at least partially overlapping with the actual dose.

CodePudding user response:

Dplyr answer:

library(dplyr)
df <- df |> 
  mutate(
    Overlap = case_when(
      Dose_Max < Estimate_Min ~ "OVER",
      Dose_Min > Estimate_Max ~ "BELLOW",
      TRUE ~ "IN"
      )
    )

  ID Estimate_Min Estimate_Max Dose_Min Dose_Max Overlap
1  1         18.0           25        7       14    OVER
2  2         15.0           22       10       13    OVER
3  3          3.0            8        4        5      IN
4  4         11.0           12       18       20  BELLOW
5  5          0.5           18        6       12      IN

CodePudding user response:

Not the most elegant way

df=structure(list(ID = 1:5, Estimate_Min = c(18, 15, 3, 11, 0.5), 
    Estimate_Max = c(25L, 22L, 8L, 12L, 18L), Dose_Min = c(7L, 
    10L, 4L, 18L, 6L), Dose_Max = c(14L, 13L, 5L, 20L, 12L)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5"))

ifelse(
  rowSums(df[c("Estimate_Min","Estimate_Max")]>df[c("Dose_Min","Dose_Max")])==2,
  "OVER",
  ifelse(
    rowSums(df[c("Estimate_Min","Estimate_Max")]<df[c("Dose_Min","Dose_Max")])==2,
    "BELOW",
    "IN"
  )
)

      1       2       3       4       5 
 "OVER"  "OVER"    "IN" "BELOW"    "IN"

Another option

tmp=c("IN","BELOW","OVER")
tmp[(2*(df$Estimate_Min>df$Dose_Max) 1*(df$Estimate_Max<df$Dose_Min)) 1]

[1] "OVER"  "OVER"  "IN"    "BELOW" "IN"
  •  Tags:  
  • r
  • Related