Tom
Tom

Reputation: 136

Finding the intersect of two lines from a data frame

I have my dataframe set up like this:

set.seed(50)
m     <- matrix(nrow=4,ncol=9)
m[1,] <- 0

for(i in 2:4){
  for(j in 1:9){
    m[i,j] <- m[i-1,j] + runif(1,max = .25)
  }
}

df <- data.frame(pond=rep(c('A','B','C'),4,each = 3),
                 variable=(rep(c('most','least','random'),3)),
                 rank=rep(c(0,.1,.2,.3),each=9),
                 value= as.vector(t(m)))

I'd like to find the point at which these lines intersect with the line with equation y=0.5-x as shown in this plot:

enter image description here

I've had some success finding the coordinates of intersection using the solve command as outlined here. I'm not sure how to iterate this process over all the variables and ponds in the data frame, especially as the rank at which the line crosses varies between pond/variables.

Upvotes: 1

Views: 266

Answers (1)

mra68
mra68

Reputation: 2960

set.seed(50)
m<-matrix(nrow=4,ncol=9)
m[1,]<-0

for(i in 2:4){
  for(j in 1:9){
    m[i,j]<-m[i-1,j]+runif(1,max = .25)
  }
}

df<-data.frame(pond=rep(c('A','B','C'),4,each = 3),
               variable=(rep(c('most','least','random'),3)),
               rank=rep(c(0,.1,.2,.3),each=9),
               value= as.vector(t(m)))

S <- lapply(split(df,df$pond),function(x){split(x,x$variable)})

Ix <-
  lapply( S,
          function(L)
          {
            lapply( L,
                    function(M)
                    {
                      a <- -1
                      b <- 0.5

                      intersection <- rep(NA,nrow(M)-1)

                      for ( n in 1:nrow(M)-1 )
                      {
                        x1 <- M$rank[n]
                        x2 <- M$rank[n+1]
                        y1 <- M$value[n]
                        y2 <- M$value[n+1]

                        det <- a*(x1-x2)+y2-y1
                        x <- (x1*(y2-y1)+(b-y1)*(x2-x1)) / det
                        lambda <- (a*x1-y1+b)/det

                        intersection[n] <-
                          ifelse( (0<=lambda) && (lambda<=1),
                                  x,
                                  NA )    
                      }

                      intersection
                    }
                  )
          }
        )

Result:

> Ix
$A
$A$least
[1]        NA        NA 0.2653478

$A$most
[1]        NA        NA 0.2809349

$A$random
[1]        NA        NA 0.2718672


$B
$B$least
[1]        NA        NA 0.2548668

$B$most
[1]        NA 0.1800216        NA

$B$random
[1]        NA        NA 0.2706433


$C
$C$least
[1]        NA 0.1771962        NA

$C$most
[1]        NA 0.1836434        NA

$C$random
[1]        NA        NA 0.2811595

The values in Ix are the "rank" values. NA means that the line segment doesn't intersect.

Upvotes: 1

Related Questions