Agrégation de points au réseau à l'aide de R

14

J'ai une question concernant l'agrégation spatiale dans R. Ce que j'essaie de faire est d'agréger un ensemble de données ponctuelles à une grille. Je ne sais cependant pas comment procéder, car j'ai peu d'expérience avec ce genre de choses. J'espérais que n'importe lequel d'entre vous pourrait avoir des conseils utiles / une solution possible.

Mon point de vue est un ensemble de données contenant des données géoréférencées sur les événements de conflit en Afrique (voir www.acleddata.com). Les points sont géoréférencés avec des coordonnées de latitude / longitude et contiennent des données sur le type d'événement et l'heure. Ce que je veux faire, c'est agréger ces points sur une grille de 1 x 1 degré.

Ainsi, une cellule de grille devrait contenir les informations des points de données si un événement se produisait dans cette cellule de grille. Le produit final de ceci devrait être une trame de données ou quelque chose que je peux exporter vers un fichier csv car les données sont destinées à être utilisées dans un ensemble de données de panel pour une analyse statistique.

Jusqu'à présent, j'ai chargé et tracé les données et le fichier de formes à l'aide du code ci-dessous. Je crois que je devrais utiliser la fonction over du package sp pour agréger mais je ne sais pas comment. J'espère que l'un de vous pourra vous aider.

Le code que j'ai utilisé jusqu'à présent peut être trouvé ici avec le résultat visuel correspondant là-bas .

Les suggestions pour cela dans QGIS sont également les bienvenues.

horseoftheyear
la source
Il s'agit d'une opération simple et rapide ne nécessitant rien de plus qu'un peu d'arithmétique. Mais dans quel format voulez-vous la sortie? "CSV" suggère seulement qu'il devrait s'agir d'un tableau relationnel, mais cela présente un problème: lorsque vous agrégez, chaque cellule correspondra potentiellement à un nombre variable de points. Habituellement, vous sélectionnez l'une des deux options: vous sortez un enregistrement par point (y compris l'ID de sa cellule contenant) ou vous sortez un enregistrement par cellule et incluez des résumés statistiques des points qu'il contient. De quoi avez-vous besoin?
whuber
1
Désolé, je n'ai pas précisé cela. Ce dont j'ai besoin, c'est d'un enregistrement par cellule . J'utilise le fichier csv pour créer des données de panneau au format année-cellule .
horseoftheyear

Réponses:

12

Les données téléchargées contiennent des erreurs de localisation franches, donc la première chose à faire est de limiter les coordonnées à des valeurs raisonnables:

data.df <- read.csv("f:/temp/All_Africa_1997-2011.csv", header=TRUE, sep=",",row.names=NULL)
data.df <- subset(data.df, subset=(LONGITUDE >= -180 & LATITUDE >= -90))

Le calcul des coordonnées et des identificateurs des cellules de la grille consiste simplement à tronquer les décimales à partir des valeurs de latitude et de longitude. (Plus généralement, pour les rasters arbitraires, centrez-les d'abord et mettez-les à l'échelle pour unifier la taille des cellules, tronquez les décimales, puis redimensionnez et recentrez à leur position d'origine, comme indiqué dans le code jici-dessous.) Nous pouvons combiner ces coordonnées en identificateurs uniques, les attacher à la trame de données d'entrée et écrire la trame de données augmentée sous forme de fichier CSV. Il y aura un enregistrement par point:

ji <- function(xy, origin=c(0,0), cellsize=c(1,1)) {
  t(apply(xy, 1, function(z) cellsize/2+origin+cellsize*(floor((z - origin)/cellsize))))
}
JI <- ji(cbind(data.df$LONGITUDE, data.df$LATITUDE))
data.df$X <- JI[, 1]
data.df$Y <- JI[, 2]
data.df$Cell <- paste(data.df$X, data.df$Y)

Vous souhaiterez peut-être plutôt une sortie qui résume les événements dans chaque cellule de la grille. Pour illustrer cela, calculons les nombres par cellule et sortons-les, un enregistrement par cellule:

counts <- by(data.df, data.df$Cell, function(d) c(d$X[1], d$Y[1], nrow(d)))
counts.m <- matrix(unlist(counts), nrow=3)
rownames(counts.m) <- c("X", "Y", "Count")
write.csv(as.data.frame(t(counts.m)), "f:/temp/grid.csv")

Pour les autres résumés, modifiez l' functionargument dans le calcul de counts. (Vous pouvez également utiliser un tableur ou un logiciel de base de données pour résumer le premier fichier de sortie par identifiant de cellule.)

Pour vérifier, cartographions les nombres en utilisant les centres de la grille pour localiser les symboles de la carte. (Les points situés dans la mer Méditerranée, en Europe et dans l'océan Atlantique ont des emplacements suspects: je soupçonne que beaucoup d'entre eux résultent d'un mélange de latitude et de longitude dans le processus de saisie des données.)

count.max <- max(counts.m["Count",])
colors = sapply(counts.m["Count",], function(n) hsv(sqrt(n/count.max), .7, .7, .5))
plot(counts.m["X",] + 1/2, counts.m["Y",] + 1/2, cex=sqrt(counts.m["Count",]/100),
     pch = 19, col=colors,
     xlab="Longitude of cell center", ylab="Latitude of cell center",
     main="Event counts within one-degree grid cells")

Carte de l'Afrique

Ce workflow est maintenant

  • Complètement documenté (au moyen du Rcode lui-même),

  • Reproductible (en relançant ce code),

  • Extensible (en modifiant le code de manière évidente), et

  • Raisonnablement rapide (l'ensemble de l'opération prend moins de 10 secondes pour traiter ces 53052 observations).

whuber
la source
Le code est parfaitement reproductible. J'ai cependant une question supplémentaire. Au lieu d'un résumé, comment puis-je joindre les informations du fichier de données d'entrée à la cellule de la grille créée?
horseoftheyear
1
Cela n'est pas possible avec une table de sortie , car les informations complètes pour les cellules ont une longueur variable. La bonne façon d'enregistrer c'est avec la première forme de sortie que j'ai présentée: un enregistrement par point avec un attribut d'identifiant de cellule. L'un de ces deux formats - les tableaux par point et par cellule - sera attendu par le programme statistique que vous utilisez.
whuber
1
Ah ok. Je vois ce que tu veux dire. Il suffit de créer une grille pour toutes les cellules et de la fusionner. Merci pour l'aide.
horseoftheyear
3

Eh bien, ce que vous voulez, c'est une base appelée "jointure spatiale", qui associe deux fichiers de formes et alloue la somme (nombre de comptages) à la table d'attributs résultante. Si vous recherchez "Spatial Join in R", vous trouverez de nombreux exemples même ici sur GIS.Stackexchange. J'ai rapidement googlé et trouvé par exemple ce code posté sur une liste de diffusion.

Si vous souhaitez obtenir une jointure d'attribut spatial dans QGIS, procédez comme suit:

  • Enregistrez vos formes sous forme de fichiers .shp (commande writeOGR à partir du package rgdal)
  • Chargez-les dans QGIS. Recréez votre grille vectorielle via le plugin MMQGIS (Créer -> Créer une couche de grille) avec une mise à l'échelle appropriée.
  • Utilisez l'outil "Join Attributes" du menu Vector -> Data Management. Sélectionnez un attribut de votre couche de points (il peut s'agir d'une simple colonne représentant les valeurs VRAI (1) ou FAUX (0) pour différents événements de conflit).
  • Sélectionnez votre grille et additionnez toutes les occurrences et exécutez. Ensuite, je couperais également votre grille avec une forme du continent africain.

Si la jointure échoue (ne fonctionne pas pour moi à chaque fois), alors restez sur SEXTANTE et recherchez la boîte à outils SAGA, qui a également de très bonnes fonctions de jointure.

Courlis
la source
Bien qu'il s'agisse d'une solution, elle est particulièrement complexe et inefficace étant donné que résumer les points d'une grille n'est qu'une question de quelques opérations arithmétiques simples, qui Rexcelle. Utiliser des fichiers de formes, rgdalQGIS et Sextante, c'est un peu comme recommander à quelqu'un de louer une usine industrielle automatisée moderne afin de clouer deux planches ensemble :-).
whuber
Je vais essayer cette approche ce week-end. Dans un avenir proche, je pourrais vouloir combiner divers fichiers de formes les uns avec les autres, ce qui pourrait être utile. Merci pour la contribution et les suggestions.
horseoftheyear
@whuber: C'est vrai, mais si vous souhaitez distribuer et peut-être styliser votre sortie, un fichier de formes est le choix évident. Néanmoins, bel exemple R!
Courlis
Je l'ai finalement essayé. Mais le problème avec cette approche est qu'elle résume toutes les observations au polygone. Bien que je souhaite idéalement conserver les informations sur les différents événements au fil du temps. Mais il se pourrait que j'ai fait quelque chose de mal.
horseoftheyear