2017-03-06 2 views
2

Ich habe zwei Datenrahmen, die xy-Koordinaten für verschiedene IDs zu verschiedenen Zeitpunkten haben. Ich möchte herausfinden, welcher Punkt im letzten Jahr dem Punkt im aktuellen Jahr am nächsten kommt und diese Daten in einer Liste speichern. So für dieses Beispiel Daten:Wie kann ich den nächsten Punkt für eine Liste von verschiedenen Punkten identifizieren und die ID in einer Liste speichern?

oldnames <- c('A', 'B', 'C') 
oldx <- c(0,5,10) 
oldy <- c(0,5,10) 
olddf <- data.frame(oldnames, oldx, oldy) 

newnames <- c('D','E','F') 
newx <- c(1, 6, 11) 
newy <- c(1, 6, 11) 
newdf <- data.frame(newnames, newx, newy) 

Ich möchte eine Liste erzeugen, die wie folgt aussieht:

names closest 
D  A 
E  B 
F  C 

Ich habe versucht, dies zu tun, gelten mit (wie unten), aber bei der Moment es gibt mir eine Fehlermeldung: (Fehler in mutate_impl (.data Punkte): nicht-numerisches Argument Binäroperators)

Hat jemand irgendwelche Ideen?

closestdf <- data.frame() 
apply(newdf, 1, function(row) { 
    name <- row["names"] 
    xID <- row["x"] 
    yID <- row["y"] 
    closest <- olddf %>% 
       mutate(length = sqrt((xID - oldx)^2 + (yID - oldy)^2)) %>% 
       mutate(rank = min_rank(length)) %>% 
       filter(rank == '1')%>% 
       mutate(total = '1') 
       closestdf <- rbind(closest, closestdf) 
}) 

Prost!

Antwort

2

Keine Notwendigkeit für Anrufe gelten, können wir purrr innerhalb des mutate statt:

library(tidyverse) 
newdf %>% 
    mutate(closest = 
      map2_chr(newx, newy, 
        ~as.character(olddf$oldnames)[which.min((.x - olddf$oldx)^2 + (.y - olddf$oldy)^2)] 
      ) 
) 

Gibt:

newnames newx newy closest 
1  D 1 1  A 
2  E 6 6  B 
3  F 11 101  C 

Es gibt keinen Grund, die Quadratwurzeloperation auszuführen, wenn wir brauche nicht die tatsächliche Entfernung.

Oder klarer und ausführliche mit Zwischenschritten:

newdf %>% 
    mutate(dists = map2(newx, newy, ~(.x - olddf$oldx)^2 + (.y - olddf$oldy)^2), 
     ids = map_dbl(dists, which.min), 
     closest = olddf$oldnames[ids]) 

Gibt:

newnames newx newy    dists ids closest 
1  D 1 1  2, 32, 162 1  A 
2  E 6 6   72, 2, 32 2  B 
3  F 11 101 10322, 9252, 8282 3  C 
+1

Großen Dank dafür! Für die obere Lösung, sollte es [which.min ((. X - olddf $ oldx^2) + (.y - olddf $ oldy)^2)] sein? –

+1

Ja, tut mir leid, ich war zu schnell. – Axeman

Verwandte Themen