Visualiser la direction de migration la plus probable étant donné les points avec les âges en utilisant R?

8

J'ai une question sur la meilleure façon de visualiser la direction de migration prévue compte tenu d'un ensemble de points avec des âges estimés.

Imaginez que j'ai un ensemble de coordonnées géographiques représentant les communautés. Pour chaque point, j'ai une estimation de l'âge de cette communauté. Je veux dessiner une flèche sur la carte qui indique la direction la plus probable de la migration générale au fil du temps. Je veux également que la magnitude de la flèche représente la cohérence du gradient / la confiance que nous avons qu'il existe un alignement significatif entre le temps et l'espace. Je ne pose pas de question sur la théorie du processus de migration, mais sur la façon dont vous décideriez de l'angle, de la position et de l'ampleur de la flèche.

Par exemple, les points rouges ci-dessous sont plus anciens que les points verts. Dans la première case, cela semble être une conclusion raisonnable que la migration était du sud-est. Dans la deuxième case, il n'y a pas de motif clair, donc la flèche est plus petite.

Exemple

Existe-t-il une manière standard et raisonnée de procéder? J'ai pensé à dessiner un vecteur entre le point le plus ancien et le 2e plus ancien, puis entre le 2e plus ancien et le 3e plus ancien, etc. Additionnez ensuite les vecteurs (mais comment décider de l'emplacement de départ?). Ou peut-être devez-vous prendre les vecteurs entre toutes les paires de points et les pondérer par les âges relatifs? Ou peut-être que je dois déterminer les contours, puis tracer un chemin qui commence au point le plus élevé et se dirige vers la descente?

Une solution basée sur R serait idéale.

Sean Roberts
la source
cela me rappelle les modèles de régression ou les surfaces, calculant la direction du flux.
Andreas Müller
1
Oui, l'ajustement z~x+yaux points de données donne l'équation d'un plan qui correspond aux points, puis tracez une flèche avec une direction définie par les coefficients et la taille en fonction de la signification. Centrez la flèche au centre de gravité des points.
Spacedman
C'est une excellente question (+1). Je recommanderais d'ajouter votre modification comme réponse. Le fait de coller la modification à la question laisse votre question un peu floue. Il est préférable d'ouvrir une nouvelle question demandant comment améliorer les fonctionnalités de votre code.
Aaron

Réponses:

2

Voici ma solution actuelle, basée sur la suggestion ci-dessus pour adapter une surface. Cette solution ne traite pas la mise à l'échelle correctement, donc les coordonnées et les valeurs z doivent être petites (par exemple entre -1 et 1).

drawDirection = function(x,y,z){
  # use linear model to fit surface
  m = lm(z ~ x+y)

  # Treat coefficeints like vectors and 
  # define arrow start and end points
  arrow = c(0,0,
            m$coefficients["x"],
            m$coefficients['y'])
  # Move arrow to centroid
  adj.x = mean(x)- (m$coefficients["x"]/2)
  adj.y = mean(y)- (m$coefficients["y"]/2)
  arrow = arrow + c(adj.x,adj.y,adj.x,adj.y)

  # colours for points
  # Yellow = higher = more recent
  z.col = heat.colors(10)[as.numeric(cut(z,breaks=10))]
  # Plot points with some extra space around
  plot(x,y, col=z.col, pch=16,
       xlim=c(min(x)-sd(x)*2,max(x)+sd(x)*2),
       ylim=c(min(y)-sd(y)*2,max(y)+sd(y)*2))
  # Plot arrow
  # (scale width by 10 x the R squared)
  arrows(arrow[1],arrow[2],arrow[3],arrow[4],
         lwd = 1+(10*summary(m)$adj.r.squared))
}

par(mfrow=c(1,2))

# Simulate some data
n = 30
# Correlated North-East
x = runif(n,0,1)
y = jitter(x,amount=1)
z = jitter(x+y,amount=1)
x = x
y = y
drawDirection(x,y,z)

# Uncorrelated
x2 = runif(n,0,1)
y2 = runif(n,0,1)
z2 = runif(n,0,1)

drawDirection(x2,y2,z2)

Production

Cependant, je pense que je fais une mauvaise mise à l'échelle - si j'augmente la plage de x et y, la flèche ne se met pas à l'échelle correctement:

# Correlated North-East, 
#  with x and y variables between 0 and 360
x = runif(n,0,1)
y = jitter(x,amount=1)
z = jitter(x+y,amount=1)
x = x*360
y = y*360
drawDirection(x,y,z)

La longueur de la flèche n'est pas mise à l'échelle correctement

Donc, pour l'instant, vous pouvez mettre à l'échelle les coordonnées géographiques et la valeur z.

Sean Roberts
la source