Advertisement
matthewrmata

Release Point Algorithm (Display Images)

Jun 3rd, 2015
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 16.69 KB | None | 0 0
  1. ###################################
  2. # Release_Point_Combo_Home_Away.r #
  3. ###################################
  4.  
  5. # This program estimates the release point of a pitcher using PITCHf/x data.
  6.  
  7. # Written by Matthew Mata, May 2015 (matthewrmata@gmail.com)
  8.  
  9. #############
  10. # LIBRARIES #
  11. #############
  12.  
  13. # This library calls MySQL
  14. library('RODBC');
  15. library('calibrate');
  16. library('diagram');
  17.  
  18. # Set the working directory and include the spatial clustering algorithm
  19. setwd("R Scripts/Release Point Scripts");
  20. source("inc_k_means_fast.r");
  21.  
  22. #############
  23. # FUNCTIONS #
  24. #############
  25.  
  26. # This function sets the x- and z-coordinates to a distance y
  27. release_dist <- function(Pitch,y){
  28.     # Define the arrays
  29.     x0 <- Pitch$x0;
  30.     y0 <- Pitch$y0;
  31.     z0 <- Pitch$z0;
  32.     vx0 <- Pitch$vx0;
  33.     vy0 <- Pitch$vy0;
  34.     vz0 <- Pitch$vz0;
  35.     ax <- Pitch$ax;
  36.     ay <- Pitch$ay;
  37.     az <- Pitch$az;
  38.     # Loop over the pitches and move the data for each pitch to distance y
  39.     a <- 0.5*ay;
  40.     b <- vy0;
  41.     c <- y0 - y;
  42.     t_rel <- (-b - sqrt(b^2 - 4*a*c))/(2*a);
  43.     x <- 0.5*ax*t_rel^2 + vx0*t_rel + x0;
  44.     z <- 0.5*az*t_rel^2 + vz0*t_rel + z0;
  45.     # Store the new data as a list and return
  46.     RP <- list(x = x, z = z);
  47.     return(RP);
  48. }
  49.  
  50. # This function calculates the location where the cluster is smallest
  51. min_cluster <- function(Pitch,Ind,y_feet,FIRST,LAST,YEAR,SIM,H_or_A){
  52.     x0 <- Pitch$x0[Ind];
  53.     y0 <- Pitch$y0[Ind];
  54.     z0 <- Pitch$z0[Ind];
  55.     vx0 <- Pitch$vx0[Ind];
  56.     vy0 <- Pitch$vy0[Ind];
  57.     vz0 <- Pitch$vz0[Ind];
  58.     ax <- Pitch$ax[Ind];
  59.     ay <- Pitch$ay[Ind];
  60.     az <- Pitch$az[Ind];
  61.     N_p <- length(x0);
  62.     # Set the number of nodes (45 feet to 65 feet in inches)
  63.     N_y <- 241;
  64.     # Initialize the arrays for storing the data at different distances, sample means and covariances, and areas
  65.     R_x <- array(0,dim=c(N_y,N_p));
  66.     R_y <- array(0,dim=c(N_y,N_p));
  67.     R_z <- array(0,dim=c(N_y,N_p));
  68.     mu <- array(0,dim=c(N_y,2));
  69.     sig <- array(0,dim=c(N_y,2,2));
  70.     mu_temp <- array(0,dim=2);
  71.     sig_temp <- array(0,dim=c(2,2));
  72.     ellipse_area <- array(0,dim=N_y);
  73.     # Set the interval of where the release point will occur
  74.     D_y <- seq(45,65,length=N_y);
  75.     a <- 0.5*ay;
  76.     b <- vy0;
  77.     # Loop over the distances
  78.     for (i in 1:N_y){
  79.         # Set the coefficients for use in the Pythagorean theorem to solve a t^2 + b t + c = (Distance in y) for t
  80.         c <- y0 - D_y[i];
  81.         t <- (-b - sqrt(b^2 - 4*a*c))/(2*a);
  82.         # Evaluate the distance at t
  83.         R_x[i,] <- t(0.5*ax*t^2 + vx0*t + x0);
  84.         R_y[i,] <- t(0.5*ay*t^2 + vy0*t + y0);
  85.         R_z[i,] <- t(0.5*az*t^2 + vz0*t + z0);
  86.         # Compute the sample mean and sample covariance
  87.         mu_temp <- array(0,dim=2);
  88.         sig_temp <- array(0,dim=c(2,2));
  89.         mu_temp[1] <- sum(R_x[i,])/N_p;
  90.         mu_temp[2] <- sum(R_z[i,])/N_p;
  91.         sig_temp[1,1] <- sum((R_x[i,] - mu_temp[1])^2);
  92.         sig_temp[1,2] <- sum((R_x[i,] - mu_temp[1])*(R_z[i,] - mu_temp[2]));
  93.         sig_temp[2,1] <- sig_temp[1,2];
  94.         sig_temp[2,2] <- sum((R_z[i,] - mu_temp[2])^2);
  95.         sig_temp <- sig_temp/(N_p-1);
  96.         mu[i,] <- mu_temp;
  97.         sig[i,,] <- sig_temp;
  98.         # Compute the eigenvalues and eigenvectors of the covariance matrix
  99.         ellipse <- eigen(sig[i,,]);
  100.         evalues <- ellipse$values;
  101.         evectors <- ellipse$vectors;
  102.         # Determine two standard deviations along the axes
  103.         ellipse_axes <- 2*sqrt(evalues);
  104.         # Compute the area of the ellipse
  105.         ellipse_area[i] <- pi*ellipse_axes[1]*ellipse_axes[2];
  106.     }
  107.     # Find the index corresponding to the smallest area
  108.     RP_index <- which(ellipse_area == min(ellipse_area));
  109.     # Set up the data for ellipse plotting
  110.     s <- seq(0,2*pi,length=200);
  111.     x_par <- cos(s);
  112.     y_par <- sin(s);
  113.     # Find the minimum ellipse
  114.     ellipse <- eigen(sig[RP_index,,]);
  115.     # Determine the values for plotting the ellipse
  116.     evalues <- ellipse$values;
  117.     evectors <- ellipse$vectors;
  118.     ellipse_axes <- 2*sqrt(evalues);
  119.     x_ellipse <- ellipse_axes[1]*x_par;
  120.     y_ellipse <- ellipse_axes[2]*y_par;
  121.     ellipse_matrix <- rbind(x_ellipse,y_ellipse);
  122.     ellipse_coord <- evectors%*%ellipse_matrix + mu[RP_index,];
  123.     # Set bounds for the plot
  124.     min_x <- min(R_x[RP_index,])-0.15;
  125.     max_x <- max(R_x[RP_index,])+0.15;
  126.     min_y <- min(R_z[RP_index,])-0.15;
  127.     max_y <- max(R_z[RP_index,])+0.15;
  128.     # Compute the release angle
  129.     angle <- release_angle(ellipse);
  130.     # Set the index for where the clustering occurs
  131.     cluster_ind <- round(12*(y_feet-45) + 1,digits=0);
  132.     # Determine the release point
  133.     R_Point <- round(D_y[RP_index],digits=3);
  134.     R_Point_h <- round(mu[RP_index,1],digits=3);
  135.     R_Point_v <- round(mu[RP_index,2],digits=3);
  136.     windows();
  137.     # Plot the functional for the area of the ellipses
  138.     plot(D_y,ellipse_area,type='n',xlab='Distance From Back of Home Plate (Feet)',ylab='Two Standard Deviation Ellipse Area (Square Feet)',
  139.          main = paste("Release Point Functional for ",FIRST," ",LAST," 20",YEAR," ",H_or_A,SIM,"",sep=""),xaxs='i',yaxs='i');
  140.     par(new=TRUE);
  141.     lines(D_y,ellipse_area);
  142.     par(new=FALSE);
  143.     windows();
  144.     # Plot the clustered data at the distance it was clustered
  145.     plot(R_x[cluster_ind,],R_z[cluster_ind,],col="blue",pch=20,xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='Horizontal Location (Feet)',
  146.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Pitches at ",y_feet," Ft",SIM,"",sep=""),xaxs='i',yaxs='i');
  147.     windows();
  148.     # Plot the cluster at the estimated release point
  149.     plot(R_x[RP_index,],R_z[RP_index,],col="blue",pch=20,xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='Horizontal Location (Feet)',
  150.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Est. Release Point, ",R_Point," Ft",SIM,"",sep=""),xaxs='i',yaxs='i');
  151.     par(new=TRUE);
  152.     lines(ellipse_coord[1,],ellipse_coord[2,],col='black',xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='',ylab='',lwd=2);
  153.     par(new=FALSE);
  154.     # Return the release point and angle as a list
  155.     RP_data <- list( RP_x = R_Point_h, RP_y = R_Point, RP_z = R_Point_v, RP_a = angle, RP_area = ellipse_area[RP_index] );
  156.     return(RP_data);
  157. }
  158.  
  159. # This function determines the release angle
  160. release_angle <- function(E){
  161.     # Calculate the eigenvalues and eigenvectors
  162.     evals <- E$values;
  163.     evecs <- E$vectors;
  164.     # Choose the smaller of the two eigenvalues and use the geometric definition of the dot product to compute the angle from horizontal
  165.     # This means dotting the corresponding eigenvalue with (1,0), taking the absolute value, and computing the arccosine.
  166.     if (evals[1] < evals[2]){
  167.         angle <- acos(abs(evecs[1,1]));
  168.     }
  169.     else{
  170.         angle <- acos(abs(evecs[1,2]));
  171.     }
  172.     # Return the angle
  173.     angle <- round((180/pi)*angle,digits=3);
  174.     return(angle);
  175. }
  176.  
  177. # This function determines the indices of the data that has a 'pct' percent chance or better
  178. # of belonging to the primary (largest) cluster.
  179.  
  180. Largest_Cluster <- function(K,pct){
  181.     # Determine the primary cluster
  182.     Primary <- which(K$w == max(K$w));
  183.     # Find the points with 5% or better probability of being from the primary cluster
  184.     Lrg <- which(K$C[Primary,] >= pct);
  185.     return(Lrg);
  186. }
  187.  
  188. ########
  189. # MAIN #
  190. ########
  191.  
  192. # Set the player name (PARAMETER)
  193. FIRST <- 'Corey';
  194. LAST <- 'Kluber';
  195. YEAR <- 13;
  196.  
  197. DB <- paste("MLB20",YEAR,sep="");
  198.  
  199. # Set the release distance for clustering (PARAMETER)
  200. y_feet <- 55;
  201.  
  202. # Number of points to average over for the rolling average (PARAMETER)
  203. S <- 75;
  204.  
  205. # Set the distance in feet for a change in release location (PARAMETER)
  206. marker <- 0.75;
  207.  
  208. # Set the maximal number of spatial clusters (PARAMETER)
  209. k_max <- 10;
  210.  
  211. # Set HA to "1" for Home and "2" for Away data
  212. HA <- 1;
  213.  
  214. if (HA == 1) {H_or_A <- '(H)'} else {H_or_A <- '(A)'};
  215.  
  216. print(paste("Pitcher: ",FIRST," ",LAST,", 20",YEAR," " ,H_or_A,"",sep=""));
  217.  
  218. # Set the channel (Database is MLB2014)
  219. channel <- odbcConnect(DB);
  220.  
  221. # Set the query to get the PITCHf/x data and exclude any missing entries (by finding entries missing the px value)
  222. # Also exclude intentional balls
  223. Release_Query <- paste("SELECT x0, y0, z0, vx0, vy0, vz0, ax, ay, az FROM pitches WHERE
  224.                       ab_id IN (SELECT ab_id FROM atbats WHERE
  225.                        pitcher = (SELECT eliasid FROM players WHERE first = '",
  226.                        FIRST,"' AND last = '",LAST,"') AND half = ",HA,") AND
  227.                        pitch_type <> 'IN' AND px IS NOT NULL",sep="");
  228.  
  229. # Download the pitch data
  230. Release <- sqlQuery(channel,Release_Query);
  231.  
  232. # Close the channel
  233. close(channel);
  234.  
  235. # Move the data to y_feet and assign the values of x and z to arrays
  236. RP <- release_dist(Release,y_feet);
  237. x_rel <- RP$x;
  238. z_rel <- RP$z;
  239. N_p <- length(x_rel);
  240.  
  241. # Set bounds for plotting
  242. x_rel_min <- min(x_rel) - 0.05;
  243. x_rel_max <- max(x_rel) + 0.05;
  244. z_rel_min <- min(z_rel) - 0.05;
  245. z_rel_max <- max(z_rel) + 0.05;
  246.  
  247. # Plot unclustered data
  248. windows();
  249. plot(x_rel,z_rel,col="blue",pch=20,xlim=c(x_rel_min,x_rel_max),ylim=c(z_rel_min,z_rel_max),xlab='Horizontal Location (Feet)',
  250.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", All Pitches at 55 Ft",sep=""),xaxs='i',yaxs='i');
  251.  
  252. # Arrays for storing the rolling averages (referred to in the code as "Snake")
  253. Snake_x <- array(0,dim=(N_p-S+1));
  254. Snake_z <- array(0,dim=(N_p-S+1));
  255.  
  256. # Compute the rolling averages
  257. for (i in 1:(N_p-S+1)){
  258.     Snake_x[i] <- mean(x_rel[c(i:(S-1+i))]);
  259.     Snake_z[i] <- mean(z_rel[c(i:(S-1+i))]);
  260. }
  261.  
  262. # Calculate the line integral or length of the snake
  263. line_int <- 0;
  264. for (i in 1:(N_p-S)){
  265.     line_int <- line_int + sqrt((Snake_x[i+1]-Snake_x[i])^2 + (Snake_z[i+1]-Snake_z[i])^2);
  266. }
  267.  
  268. # Print the length of the line
  269. print(paste("Length of Line: ",round(line_int,digits=3),sep=""));
  270.  
  271. # Initialize an array for storing the distance between points in the rolling average
  272. sep_dist <- array(0,dim=(N_p-2*S+1));
  273.  
  274. # Calculate the distance between disjoint, adjacent rolling averages
  275. for (i in 1:(N_p-2*S+1)){
  276.         sep_dist[i] <- sqrt((Snake_x[i] - Snake_x[i+S])^2 + (Snake_z[i] - Snake_z[i+S])^2) - marker;
  277. }
  278.  
  279. # Initialize the number for counting the location changes
  280. peak_count <- 0;
  281.  
  282. # Count the number of peaks as the number of times the distance exceeds the 'marker' for a change
  283. for (i in 1:(N_p-2*S)){
  284.     if ( sep_dist[i] < 0 && sep_dist[i+1] > 0 ){
  285.         peak_count <- peak_count + 1;
  286.     }
  287. }
  288.  
  289. # Find the location of the maximum distance of the separations
  290. if ( peak_count != 0){
  291.     loc_change <- array(0,dim=peak_count);
  292.     k <- 1;
  293.     max_dist <- 0;
  294.     for (i in 1:(N_p-2*S+1)){
  295.         if ( sep_dist[i] > max_dist ){
  296.             loc_change[k] <- i + floor(S/2);
  297.             max_dist <- sep_dist[i];
  298.         }
  299.         if ( sep_dist[i] > 0 && sep_dist[i+1] < 0 ){
  300.             k <- k + 1;
  301.             max_dist <- 0;
  302.         }
  303.     }
  304. }
  305.  
  306. # Find bounds for the plot
  307. x_min <- min(Snake_x) - 0.05;
  308. x_max <- max(Snake_x) + 0.05;
  309. z_min <- min(Snake_z) - 0.05;
  310. z_max <- max(Snake_z) + 0.05;
  311.  
  312. # Correct for grammar
  313. if (peak_count == 1) move_des = 'Move' else move_des = 'Moves';
  314.  
  315. # If there is a change (peak count is not zero), output the location where the change occurs
  316. if (peak_count != 0){
  317.     peak_loc <- array(0,dim=peak_count);
  318.     peak_output <- "Move(s) at Pitch(es): ";
  319.     for (i in 1:peak_count){
  320.         peak_loc[i] <- loc_change[i] + ceiling(S/2);
  321.         peak_output <- paste(peak_output,(loc_change[i] + ceiling(S/2)),sep="");
  322.         if (i < peak_count){
  323.             peak_output <- paste(peak_output,", ",sep="");
  324.         }
  325.     }
  326.     print(peak_output);
  327. }
  328.  
  329. # Plot the snakes, starting point (green), ending point (red), and changes (blue)
  330. windows();
  331. plot(Snake_x,Snake_z,type='n',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='Horizontal Location (Feet)',
  332.      ylab='Vertical Location (Feet)',main=paste("",FIRST," ",LAST," 20",YEAR," ",H_or_A," at ",y_feet," Ft, ",S,"-Pitch Average, ",peak_count," ",move_des,"",sep=""),xaxs='i',yaxs='i');
  333. par(new=TRUE);
  334. lines(Snake_x,Snake_z,col='black',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='');
  335. par(new=TRUE);
  336. plot(Snake_x[1],Snake_z[1],col='green',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  337. par(new=TRUE);
  338. plot(Snake_x[N_p-S+1],Snake_z[N_p-S+1],col='red',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  339. if (peak_count != 0){
  340.     for (i in 1:peak_count){
  341.         par(new=TRUE);
  342.         plot(Snake_x[loc_change[i]],Snake_z[loc_change[i]],col='blue',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  343.     }
  344. }
  345. par(new=FALSE);
  346.  
  347. # Set up parameters for plotting with more than one release point location
  348. if (peak_count != 0){
  349.     # The number of pitches in each cluster
  350.     pitch_subcount <- array(0,dim=(peak_count+1));
  351.     # The breaks between clusters
  352.     peak_loc <- c(1,peak_loc,N_p+1);
  353.     # Fill in the sub-count
  354.     for (i in 1:(peak_count+1)){
  355.         pitch_subcount[i] <- peak_loc[i+1] - peak_loc[i];
  356.     }
  357.     # Set up the colours for plotting the clusters (more colours can be added if needed)
  358.     color_wheel <- c('red', 'blue', 'green', 'orange', 'black', 'purple', 'brown', 'pink', 'gray', 'goldenrod');
  359. }
  360.  
  361. # Check if more than one cluster
  362. if (peak_count != 0){
  363.     windows();
  364.     plot(Snake_x,Snake_z,type='n',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='Horizontal Location (Feet)',
  365.          ylab='Vertical Location (Feet)',main=paste("",FIRST," ",LAST," 20",YEAR," ",H_or_A," at ",y_feet," Ft, ",S,"-Pitch Average, ",peak_count," ",move_des,"",sep=""),
  366.          xaxs='i',yaxs='i');
  367.     # The breaks between clusters
  368.     for (i in 1:(peak_count+1)){
  369.         par(new=TRUE);
  370.         num_elem <- max(peak_loc[i+1] - peak_loc[i] - S,1);
  371.         Snake_x_temp <- array(0,dim=num_elem);
  372.         Snake_z_temp <- array(0,dim=num_elem);
  373.         avg_size <- min((S-1),(peak_loc[i+1] - peak_loc[i] - 1));
  374.         for (j in peak_loc[i]:(peak_loc[i] + num_elem - 1)){
  375.             Snake_x_temp[j-peak_loc[i]+1] <- mean(x_rel[c(j:(avg_size+j))]);
  376.             Snake_z_temp[j-peak_loc[i]+1] <- mean(z_rel[c(j:(avg_size+j))]);
  377.         }
  378.         lines(Snake_x_temp,Snake_z_temp,col=color_wheel[i],xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='');
  379.         par(new=TRUE);
  380.         plot(Snake_x_temp[1],Snake_z_temp[1],col='green',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  381.         par(new=TRUE);
  382.         plot(Snake_x_temp[num_elem],Snake_z_temp[num_elem],col='red',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  383.         par(new=TRUE);
  384.         textxy(Snake_x_temp[1],Snake_z_temp[1],toString(i),col='black',cex=1,offset=1,m=c(x_min,z_min),lwd=2);
  385.         par(new=TRUE);
  386.         textxy(Snake_x_temp[num_elem],Snake_z_temp[num_elem],toString(i),col='black',cex=1,offset=1,m=c(x_min,z_min),lwd=2);
  387.     }
  388.     par(new=FALSE);
  389. }
  390.  
  391. # If the number of peaks is not zero, process each cluster to find the release point
  392. if (peak_count != 0){
  393.     windows();
  394.     # Plot the clusters
  395.     for(i in 1:(peak_count+1)){
  396.         plot(x_rel[c(peak_loc[i]:(peak_loc[i+1]-1))],z_rel[c(peak_loc[i]:(peak_loc[i+1]-1))],col=color_wheel[i],
  397.              xlim=c(x_rel_min,x_rel_max),ylim=c(z_rel_min,z_rel_max),pch=20,xlab = '', ylab='',xaxs='i',yaxs='i');
  398.              par(new=TRUE);
  399.     }
  400.     title(main=paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Pitches at ",y_feet," Ft, ",peak_count+1," Temporal Clusters",sep=""),xlab = 'Horizontal Location (Feet)',
  401.           ylab = 'Vertical Location (Feet)');
  402.     par(new=FALSE);
  403.     # Compute results for all clusters
  404.     for (i in 1:(peak_count+1)){
  405.         # Set the indices for the points in the cluster
  406.         C_Ind <- c(peak_loc[i]:(peak_loc[i+1]-1));
  407.         RP_C <- list(x=RP$x[C_Ind],z=RP$z[C_Ind]);
  408.         # Cluster the data to remove any outliers/extra clusters
  409.         K <- inc_k_means_fast(RP_C,10^(-4),500,k_max);
  410.         # Get the indices related to the largest cluster
  411.         L_Ind <- Largest_Cluster(K,0.05);
  412.         Release_C <- list( x0=Release$x0[C_Ind], y0=Release$y0[C_Ind], z0=Release$z0[C_Ind],
  413.                            vx0=Release$vx0[C_Ind], vy0=Release$vy0[C_Ind], vz0=Release$vz0[C_Ind],
  414.                            ax=Release$ax[C_Ind], ay=Release$ay[C_Ind], az=Release$az[C_Ind]);
  415.         # Plot the clusters and output the results to the console
  416.         SIM <- paste(", Cluster #",i,"",sep="");
  417.         T_loc <- min_cluster(Release_C,L_Ind,y_feet,FIRST,LAST,YEAR,SIM,H_or_A);
  418.         print(paste("Cluster #",i," Percentage: ",length(L_Ind),"/",length(C_Ind)," = ",round(100*length(L_Ind)/length(C_Ind),digits=1),"%",sep=""));
  419.         print(paste("Cluster #",i," Distance: (",T_loc$RP_x,", ",T_loc$RP_y,", ",T_loc$RP_z,")",sep=""));
  420.         print(paste("Cluster #",i," Angle: ",T_loc$RP_a,sep=""));
  421.         print(paste("Cluster #",i," Area: ",round(T_loc$RP_area,digits=3),sep=""));
  422.     }
  423. }
  424.  
  425. # Compute the results for a single cluster
  426. if(peak_count == 0){
  427.     # Cluster the data to remove any outliers/extra clusters
  428.     K <- inc_k_means_fast(RP,10^(-4),500,k_max);
  429.     # Get the indices related to the largest cluster
  430.     L_Ind <- Largest_Cluster(K,0.05);
  431.     SIM <- '';
  432.     T_loc <- min_cluster(Release,L_Ind,y_feet,FIRST,LAST,YEAR,SIM,H_or_A);
  433.     print(paste("Cluster Percentage: ",length(L_Ind),"/",N_p," = ",round(100*length(L_Ind)/N_p,digits=1),"%",sep=""));
  434.     print(paste("Cluster Distance: (",T_loc$RP_x,", ",T_loc$RP_y,", ",T_loc$RP_z,")",sep=""));
  435.     print(paste("Cluster Angle: ",T_loc$RP_a,sep=""));
  436.     print(paste("Cluster Area: ",round(T_loc$RP_area,digits=3),sep=""));
  437. }
  438.  
  439. ###################
  440. # RESET DIRECTORY #
  441. ###################
  442.  
  443. setwd("~");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement