2015-01-07 13 views
5

ähnlich wie meine vorherigen Frage: Closest point to a pathPunkte am nächsten zu einem geschätzten Weg

Ich möchte in der Lage sein, all Zentren zu finden, die am nächsten zu einem Weg sind. Einige der Daten fehlen jedoch im Pfad und ich würde gerne lineare Segmente verwenden, um zwischen Punkten zu interpolieren, um einen möglichen Pfad zu "schätzen" und dennoch wahrscheinliche Zentren zu finden, die diesem "geschätzten Pfad" nahe gekommen wären.

set.seed(1) 
n <- 10000 
x <- 100*cumprod(1 + rnorm(n, 0.0001, 0.002)) 
y <- 50*cumprod(1 + rnorm(n, 0.0001, 0.002)) 

# original path 
path <- data.frame(cbind(x=x, y=y)) 

# path with missing points/points every hundred 
path.w.missing <- path[seq(1,n,by=100),] 


centers <- expand.grid(x=seq(0, 500,by=0.5) + rnorm(1001), 
         y=seq(0, 500, by=0.2) + rnorm(2501)) 

centers$id <- seq(nrow(centers)) 

Kurz von Millionen von linearen Punkten zwischen den gegebenen Punkten auf dem Weg zu simulieren .... Ich bin nicht sicher, wie man dies zu tun gehen würde ...

Für mich ist es ein bisschen wie den Schnittpunkt einer Linie und einer Matrix von Zellen finden ... von Arten .... aber vielleicht bin ich meilenweit entfernt ...

Jede Hilfe würde sehr geschätzt werden.

+0

Meinen Sie alle Punkte zu finden, die innerhalb einer bestimmten Schwelle auf dem Weg liegen? –

+0

Teilen Sie den Pfad in Liniensegmente. Bestimmen Sie für jedes Segment den nächsten Punkt. Wiederholen Sie die Segmente mit einer Version von apply. Es ist am einfachsten zu verstehen, wenn Sie das Segment horizontal oder vertikal drehen, so dass die Entfernung zu den Punkten nur die y- (oder x-) Koordinate ist. –

+0

Wenn das Geben einer Schwelle der einzig mögliche Weg ist, dann ja glücklich, einen Schwellenwert zum Problem einzuführen ... aber im Idealfall nicht ... –

Antwort

-1

Verwenden Sie die smooth.spline Funktion (eine Glättung Spline Fit)

mx=path.w.missing$x 
my=path.w.missing$y 
s<-smooth.spline(mx,my) 
plot(mx,my) 
lines(s) #draw the estimated path 

enter image description here

predict(s,1:10) #And now you can generate all the points on the estimated path 

> predict(s,1:10) 
$x 
[1] 1 2 3 4 5 6 7 8 9 10 

$y 
[1] 2.418294 2.904019 3.389744 3.875469 4.361195 4.846920 5.332645 5.818370 6.304095 6.789820 

Und Sie das lineare Modell es passen können.

> summary(lm(my~mx)) 

Call: 
lm(formula = my ~ mx) 

Residuals: 
    Min  1Q Median  3Q  Max 
-12.772 -8.642 3.112 5.831 17.237 

Coefficients: 
      Estimate Std. Error t value Pr(>|t|)  
(Intercept) -12.60098 3.46583 -3.636 0.000444 *** 
mx   0.56579 0.02138 26.469 < 2e-16 *** 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 7.896 on 98 degrees of freedom 
Multiple R-squared: 0.8773, Adjusted R-squared: 0.876 
F-statistic: 700.6 on 1 and 98 DF, p-value: < 2.2e-16 

wie Sie sehen können, S. < 0,05, so meine und mx als Linie passen:

my=-12.60098+0.56579*mx 

ggplot2 kann diese Linie ziehen leicht:

d=data.frame(mx,my) 
library(ggplot2) 
ggplot(d,aes(mx,my))+geom_point()+geom_smooth(method="lm") 

enter image description here

angenommen, dass eine Zeile Ax+By+C=0 ist und der Punkt (X0,Y0) ist , Zeigen Sie auf den Zeilenabstand:

|AX0+BY0+C|/√(A²+B²) 

so in diesem Fall 0,56579 * mx-my-12,60098 = 0, A = 0,56579, B = -1, C = -12,60098, ist es einfach, den Abstand zu berechnen, die von Zeigen Sie auf Linie und suchen Sie den nächsten Punkt zur Linie.

Weiter mehr, wenn Sie den nächsten Punkt finden möchten, entfernen Sie den Nenner √ (A² + B²) würde die Art nicht beeinflussen, so die Optimierung der Formel:

|AX0+BY0+C| 

Ergebnis

> for(i in 1:2503501){ 
+ temp=abs(centers[[1]][i]*0.56579-centers[[2]][i]-12.60098) 
+ if(m>temp){ 
+ m=temp 
+ pos=i 
+ } 
+ } 
> m 
[1] 2.523392e-05 
> pos 
[1] 638133 

Verwenden Sie den Rcpp, um den Test des Programms zu beschleunigen.cav“

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
int closest(NumericVector a, NumericVector b) { 
    int length = a.size(); 
    double temp,m=10000; 
    int pos=0; 
    for(int i=0;i<length;i++){ 
    temp=a[i]*0.56579-b[i]-12.60098; 
    if(temp>=0){ 
     if(m>temp){m=temp;pos=i;}  
    }else{ 
     if(m>-temp){m=-temp;pos=i;} 
    } 
    } 
    return pos+1; 
} 

Ergebnis (die RCPP kosten etwa 2 Sekunden):

> sourceCpp("test.cpp") 
> closest(centers[[1]],centers[[2]]) 
[1] 974698 
> abs(centers[[1]][974698]*0.56579-centers[[2]][974698]-12.60098) 
[1] 0.0002597022 
+1

Danke, aber ich hatte speziell nach dem linearen geschätzten Pfad zwischen den Punkten gefragt, und zweitens suche ich nach Punkten auf dem Gitter, die diesem Pfad am nächsten sind, siehe die vorhergehende Frage –

1

Würden diese Hilfe:

## create data 
set.seed(1) 
n <- 10000 
x <- 100 * cumprod(1 + rnorm(n, 0.0001, 0.002)) 
y <- 50 * cumprod(1 + rnorm(n, 0.0001, 0.002)) 

# original path 
path <- data.frame(cbind(x=x, y=y)) 

# path with missing points/points every hundred 
path.w.missing <- path[seq(1,n,by=100),] 


## proposed solution 
library(raster) 

l <- SpatialLines(list(Lines(list(Line(path.w.missing)), "1"))) 
r <- raster(extent(bbox(l)), res = c(0.5, 0.2)) 
r <- rasterize(l, r, field = 1) 

## xy will be a matrix 
xy <- rasterToPoints(r) 

plot(r) 
points(xy) 
points(path.w.missing, col = "red") 

enter image description here

0

Das Paket marmap genau das tut, was Sie brauchen :

library(marmap) 
bcenters <- as.bathy(centers) 
out <- path.profile(path.w.missing,bcenters) 

     lon  lat dist.km depth 
2 100.0512 50.04129 0.00000 247451 
3 101.2070 50.11430 82.87177 247450 
4 101.3687 50.18730 95.33454 247449 
5 101.5973 50.26030 112.81665 248453 
6 102.6877 50.33330 190.48139 248454 
7 103.2105 50.40630 228.37510 248458 

Die id ist in der Spalte depth. Diese Funktion wurde codiert, um Tiefe in einer bathymetrischen Matrix entlang eines Pfades zu erhalten. Es findet, dass alle Zellen der bathymetrischen Matrix unter dem Pfad "bellen" (d. H. Zellen, die dem Pfad am nächsten sind) und gibt den Wert dieser Zellen aus. Indem Sie Ihr centers Objekt in eine Matrix der Klasse bathy transformieren, wird Ihre Spalte id verwendet, als wäre es die Tiefe. Daher gibt path.profile() die id der Zellen, die Ihrem Pfad am nächsten sind, in der Spalte depth aus.

Hier beginnen Sie mit 100 Punkten in Ihrem path.w.missing Objekt. path.profile() bekommt man die ID der

nrow(out) 
795 

Zellen, die am nächsten zu diesem Weg sind.

Hier ist ein Diagramm der path.w.missing Daten mit den nächsten Punkten in rot überlagert:

plot(path.w.missing,type="o",cex=.3, lwd=5) 
points(out[,1],out[,2], col=rgb(1,0,0,.8), cex=.3) 

enter image description here

Verwandte Themen