2010-09-06 3 views
31

J'ai (encore) un problème avec la combinaison des trames de données dans R. Mais cette fois, on est un SpatialPolygonDataFrame (SPDF) et l'autre est data.frame habituel (DF). Le SPDF a environ 1000 lignes le DF que 400. Les deux ont une colonne commune, QDGCComment attacher un simple data.frame à un SpatialPolygonDataFrame dans R?

Maintenant, j'ai essayé

oo <- merge(SPDF,DF, by="QDGC", all=T) 

mais cela ne se traduit par une data.frame normale, pas une trame de données de polygone spatiale plus J'ai lu ailleurs, que cela ne fonctionne pas, mais je ne comprenais pas quoi faire dans un tel cas (doit faire quelque chose avec les colonnes ID, fusionner les utilisations)

oooh une telle question difficile, je pose. ..

Merci! Jens

Répondre

40

Soit df = trame de données, sp = objet polygone spatial et par = nom ou numéro de colonne de la colonne commune. Vous pouvez ensuite fusionner la trame de données dans l'objet sp en utilisant la ligne de code suivante

[email protected] = data.frame([email protected], df[match([email protected][,by], df[,by]),]) 

Voici comment le code fonctionne. La fonction de correspondance à l'intérieur aligne les colonnes afin que l'ordre soit préservé. Donc, lorsque nous le fusionnons avec sp @ data, l'ordre est correctement préservé. Une vérification rapide pour voir si le code a fonctionné est d'inspecter les deux colonnes correspondant à la colonne commune et voir si elles sont identiques (les colonnes communes sont dupliquées et il est facile d'enlever la copie, mais je la garde comme c'est un bon contrôle)

+1

Merci beaucoup! Tu as sauvé ma soirée! Et probablement aussi toute la semaine! Cela a parfaitement fonctionné. – Jens

+0

@Ramnath Cette solution fonctionnera-t-elle si la trame de données spatiales a plus de lignes (polygones) que les données fusionnées? Et aussi dans le cas contraire - quand il y a plus d'observations dans les données jointes? – radek

+0

En quoi cela serait-il différent si les deux objets sont 'SpatialP * DataFrame's? – gregmacfarlane

6

La fusion peut produire une image avec plus de lignes que les originaux s'il n'y a pas un mappage 1-1 simple des deux données. Dans ce cas, il faudrait copier toute la géométrie et créer plusieurs polygones, ce qui n'est probablement pas une bonne chose.

Si vous disposez d'une dataframe ayant le même nombre de lignes qu'un SpatialPointsDataFrame, vous pouvez remplacer directement l'emplacement @data.

library(sp) 
example(overlay) # to get the srdf object 
[email protected] 
spplot(srdf) 
[email protected]=data.frame(x=runif(3),xx=rep(0,3)) 
spplot(srdf) 

si vous obtenez le nombre de lignes mal:

[email protected]=data.frame(x=runif(2),xx=rep(0,2)) 
spplot(srdf) 
Error in data.frame(..., check.names = FALSE) : 
    arguments imply differing number of rows: 3, 2 
+0

Ok je l'ai fait l'follwing: (1) oo <- fusion (SPDF, DF, par = "QDGC" , all = T) (2) SPDF @ data <- oo (3) plot (SPDF) les données sont maintenant présentes mais dans un très mauvais ordre. peut-être devrais-je trier quelque chose? – Jens

+0

aïe. J'aurais dû vérifier ça. – Spacedman

2

Peut-être la fonction joinCountryData2Map dans le package rworldmap peut donner de l'inspiration. (Mais je peux me tromper, comme je l'étais la dernière fois.)

16

Il est aussi facile que cela:

require(sp) # the trick is that this package must be loaded! 

oo <- merge(SPDF,DF, by="QDGC") 

J'ai testé par moi-même. Mais cela ne fonctionne que si vous utilisez merge from package sp. C'est la valeur par défaut lorsque le paquet sp est chargé. La fonction merge est alors surchargée et sp::merge est utilisée si le premier argument est une structure spatiale.

+1

Cela a très bien fonctionné pour moi! Cependant, je pense qu'il est utile de signaler que certains problèmes peuvent apparaître si la base de données et le SPDF n'ont pas le même nombre de lignes. J'ai continué à recevoir une erreur ("nombre d'objets incompatibles") provenant de ce problème. Enfin, j'ai été capable d'effectuer la fusion en ajoutant "all.x = TRUE" (où x est le SPDF). –

0

Une autre solution consiste à utiliser la fonction append_data du package tmaptools. Elle est appelée avec ces arguments:

append_data(shp, data, key.shp = NULL, key.data = NULL, 
    ignore.duplicates = FALSE, ignore.na = FALSE, 
    fixed.order = is.null(key.data) && is.null(key.shp)) 

Il est un peu dommage qu'il appelle append car je comprendrais append sens plus ina de rbind et nous voulons avoir quelque chose comme join ou merge ici.En ignorant ce fait, la fonction est vraiment utile pour s'assurer que vos jointures sont correctes et si certaines lignes ne sont présentes que d'un côté de la jointure. A partir de la documentation:

Sous couverture (articles de forme qui ne correspondent pas à des enregistrements de données), sur la couverture (enregistrements de données qui ne correspondent pas à la forme des éléments respectivement), ainsi que l'existence de valeurs-clés dupliquées sont automatiquement vérifié et signalé via les messages de la console. Avec under_coverage et over_coverage la sous et sur la couverture les principales valeurs du dernier appel append_data peut être récupéré,

Questions connexes