My code is structured so that I create an ellipse through my first three points of data. Then I go through each next row, and if the point falls outside the ellipse, I record the minimum distance between the point and ellipse. These points have datetime associated with it so I can only keep points 10 minutes old in my ellipse (so it doesn’t get too big). The code works great until I have to process 100K+ of observations. Then the process time goes from minutes to hours. My question is, is there any part of my for loop portion of code that I can restructure to cut process time? I vectorized what I could (I think), and I know taking conditions out of for loop helps but now sure how to do it. Code below for reference. Any help is greatly appreciated.

```
library(sp)
library(cluster)
#create new empty column in dataframe
df$Distances <- NA
#get first three points and fit an ellipse around it
FlashPoints <- cbind(df$Lat(1:3),df$Long(1:3))
EllipseShape <- ellipsoidhull(FlashPoints)
EllipseShape
#get set of points that represent ellipse
EllipsePoints <- predict(EllipseShape)
EllipseGroup <- cbind(EllipsePoints(,2),EllipsePoints(,1))
#function to check if the next flashpoint (xp, yp) belongs to the ellipse with parameters a,b,... with tolerance eps
onEllipse <- function (xp, yp, a, b, x0, y0, alpha, eps=1e-3) {
return(abs((cos(alpha)*(xp-x0)+sin(alpha)*(yp-y0))^2/a^2+(sin(alpha)*(xp-x0)-cos(alpha)*(yp-y0))^2/b^2 - 1) <= eps)
}
#function to check if the point (xp, yp) is inside the ellipse with parameters a,b,...
insideEllipse <- function (xp, yp, a, b, x0, y0, alpha) {
return((cos(alpha)*(xp-x0)+sin(alpha)*(yp-y0))^2/a^2+(sin(alpha)*(xp-x0)-cos(alpha)*(yp-y0))^2/b^2 <= 1)
}
#loop from row 4 to last row
for (i in 4:nrow(df)){
#get location of next point
nextFlash <- cbind(df$Long(i),df$Lat(i))
#Establish/Re-establish parameters
xp <- df$Lat(i)
yp <- df$Long(i)
x0 <- EllipseShape$loc(1) # centroid locations
y0 <- EllipseShape$loc(2)
eg <- eigen(EllipseShape$cov)
axes <- sqrt(eg$values)
alpha <- atan(eg$vectors(1,1)/eg$vectors(2,1)) # angle of major axis with x axis
a <- sqrt(EllipseShape$d2) * axes(1) # major axis length
b <- sqrt(EllipseShape$d2) * axes(2) # minor axis length
#Check to see if next point is outside the ellipse, then get distance. If it is, add to distance list
if((insideEllipse(xp, yp, a, b, x0, y0, alpha)==FALSE) && onEllipse(xp, yp, a, b, x0, y0, alpha)==FALSE){
nextDist <- min(spDistsN1(EllipseGroup, nextFlash, longlat = TRUE))
df$Distances(i) <- nextDist
#Omit points 10 minutes old from group
movingGroup <- subset(df(1:i,), difftime(df$DateTime(1:i),df$DateTime(i),units = "mins")<10)
movingTstorm
FlashPoints <- cbind(movingGroup$Lat(1:i),movingGroup$Long(1:i))
FlashPoints
#Fit an ellipse around flashpoints
EllipseShape <- ellipsoidhull(FlashPoints)
EllipseShape
#Get set of points that make an ellipse
EllipsePoints <- predict(EllipseShape)
EllipseGroup <- cbind(EllipsePoints(,2),EllipsePoints(,1))
}
next(i)
}
}
```
```