2

Working in R, I am attempting to plot stream cross sections, interpolate a point at an intersection opposite an identified "bankful" point, and calculate the area under the bankful line. It is part of a loop that is processing many cross sections. The best solution I have come up with is using the approx function, however all of the points are not exactly on the point of intersection and I have not been able to figure out what I am doing wrong.

It is hard to provide sample data since it is part of a loop, but the sample of code below produces the result in the image. The blue triangle is supposed to be at the point of intersection between the dashed "bankful" line and the solid cross section perimeter line.

###sample data

stn.sub.sort <- data.frame(dist = c(0,1.222,2.213,2.898,4.453,6.990,7.439,7.781,8.753,10.824,10.903,13.601,17.447), depth=c(-0.474,-0.633,0,-0.349,-1.047,-2.982,-2.571,-3.224,-3.100,-3.193,-2.995,-0.065,-0.112), Bankful = c(0,0,0,0,1,0,0,0,0,0,0,0,0))

###plot cross section with identified bankful
plot(stn.sub.sort$dist,
     as.numeric(stn.sub.sort$depth),
     type="b",
     col=ifelse(stn.sub.sort$Bankful==1,"red","black"),
     ylab="Depth (m)",
     xlab="Station (m)",
     ylim=range(stn.sub.sort$depth),
     xlim=range(stn.sub.sort$dist),
     main="3")


###visualize bankful line of intersection
abline(h=stn.sub.sort$depth[stn.sub.sort$Bankful==1],
       lty=2,
       col="black")

###approximate point at intersection
index.bf=which(stn.sub.sort$Bankful==1)

index.approx<-which(stn.sub.sort$dist>stn.sub.sort$dist[index.bf])

sbf <- approx(stn.sub.sort$depth[index.approx],
            stn.sub.sort$dist[index.approx],
            xout=stn.sub.sort$depth[index.bf])  

###plot opposite bankful points 
points(sbf$y,sbf$x,pch=2,col="blue")

Sample cross section

thelatemail
  • 91,185
  • 12
  • 128
  • 188
  • 1
    You have 13 points here which you could type out manually and insert into `stn.sub.sort <- data.frame(dist = c(), depth=c(), Bankful = c())`. It's an interesting question, but adding example data would make it a lot simpler to start finding an answer. – thelatemail May 19 '20 at 22:56
  • Thank you for the reply. I added sample data. – Benji Downing May 19 '20 at 23:49

1 Answers1

2

So your description leaves many questions about the nature of the data that you will have to deal with. I am going to assume that it will be roughly like your example - down from the first bankful point, then going back up with the curve crossing the depth of the bankful point just one more time.

With that assumption, it is easy to find the point before and the point after the crossing point. You just need to draw the line between those two points and solve for the correct dist value. I do this below by using approxfun to get the inverse function of the line connecting the two points. Then we can just plug in to get the dist-value of the crossing point.

BankfulDepth = stn.sub.sort$depth[stn.sub.sort$Bankful==1]
Low = max(which(stn.sub.sort$depth < BankfulDepth))

InvAF = approxfun(stn.sub.sort$depth[c(Low,Low+1)], 
            stn.sub.sort$dist[c(Low,Low+1)])
points(InvAF(BankfulDepth), BankfulDepth, pch=2,col="blue")

Plot with correct point added.

G5W
  • 36,531
  • 10
  • 47
  • 80
  • This is a really elegant solution, thank you. There are some that are braided with multiple channels, and some that will be opposite, but in general they will look very similar to this. Your solution will definitely translate well to the other forms. – Benji Downing May 20 '20 at 01:37