Lasse Lasse - 2 months ago 7
R Question

R: Find intersection of two vectors

I have two vectors. I need to find the intersection between these two, and do a nice plot of it.

So, here is a very simple data frame example:

df <- data.frame( id <- c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2),
p <-c(5,7,9,11,13,15,17,19,21,23,20,18,16,14,12,10,8,6,4,2 ),
q <-c(3,5,7,13,19,31,37,53,61,67,6,18,20,24,40,46,66,70,76,78))
colnames(df) <- c("id","price","quantity")

supply <- df[df$id == 1,]
demand <- df[df$id == 2,]

plot( x = supply$quantity, y = supply$price, type = "l", ylab = "price", xlab = "quantity")
lines(x = demand$quantity , y = demand$price, type = "l")
grid()


Now, I can plot them and find the intersection manually, but can you make R calculate the intersection between these two lines?

The data can take huge jumps, and the lines can go from very step to nearly horizontal.

Answer

Be careful creating your data frame. You want =, not <-. Also, make id a factor, for clarity.

df <- data.frame( 
  id       = factor(rep(c("supply", "demand"), each = 10)),
  price    = c(5,7,9,11,13,15,17,19,21,23,20,18,16,14,12,10,8,6,4,2 ),
  quantity = c(3,5,7,13,19,31,37,53,61,67,6,18,20,24,40,46,66,70,76,78)
)

First we define common, frequent points to evaluate the quantity at.

quantity_points <- with(
  df,
  seq(min(quantity), max(quantity), length.out = 500)
)

Now split the dataset into supply/demand parts.

by_id <- split(df[, c("price", "quantity")], df$id)

Then we use approx to calculate the price at each of these quantities, for supply and demand separately.

interpolated_price <- lapply(
  by_id,
  function(x)
  {
    with(
      x,
      approx(
        quantity,
        price, 
        xout = quantity_points
      )
    )$y       
  }
)

Finally, the crossing point is where the absolute value of the supply price minus the demand price is minimised.

index_of_equality <- with(interpolated_price, which.min(abs(supply - demand)))
quantity_points[index_of_equality]
Comments