9

Thanks to the answer given in this question I have been able to subset and draw a map of electoral divisions in part of the UK, in this case Pembrokeshire. The resulting data frame is large and contains Ordnance Survey data so it would be difficult to post here, but the data frame looks like this:

> str(bar)
'data.frame':   134609 obs. of  7 variables:
 $ long : num  214206 214203 214202 214198 214187 ...
 $ lat  : num  207320 207333 207339 207347 207357 ...
 $ order: int  1 2 3 4 5 6 7 8 9 10 ...
 $ hole : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
 $ piece: Factor w/ 12 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ group: Factor w/ 82 levels "Amroth ED.1",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ id   : chr  "Amroth ED" "Amroth ED" "Amroth ED" "Amroth ED" ...

I fed the resulting data frame to ggplot using the following code:

ggplot(bar, aes(x = long, y = lat, group = group)) +
  geom_polygon(colour = "black", fill = "grey50")

This generates the following image, which looks nice and clean. map of electoral divisions

Then I combined this with a data frame containing population data, which looks like this:

> str(mydf)
'data.frame':   60 obs. of  22 variables:
 $ ward.code  : chr  "00NSPH" "00NSPJ" "00NSPK" "00NSPL" ...
 $ id         : chr  "Amroth ED" "Burton ED" "Camrose ED" "Carew ED" ...
 $ la         : chr  "Pembrokeshire" "Pembrokeshire" "Pembrokeshire" "Pembrokeshire" ...
 $ total      : num  1237 1737 2458 1570 1976 ...
 $ age.0.4    : num  34 86 81 92 107 76 131 77 90 95 ...
 $ age.5.9    : num  45 93 83 80 138 82 111 85 132 75 ...
 $ age.10.14  : num  65 116 123 103 111 79 151 80 135 83 ...
 $ age.15.19  : num  69 90 161 126 117 93 150 87 139 103 ...
 $ age.20.24  : num  42 63 116 58 81 63 120 58 114 79 ...
 $ age.25.29  : num  46 63 73 60 86 56 90 51 108 67 ...
 $ age.30.34  : num  38 60 87 72 99 54 115 62 76 42 ...
 $ age.35.39  : num  53 105 104 82 110 81 91 76 121 82 ...
 $ age.40.44  : num  70 142 128 107 116 88 161 89 151 92 ...
 $ age.45.49  : num  71 138 172 122 128 109 192 116 190 104 ...
 $ age.50.54  : num  93 136 204 108 133 119 168 125 174 99 ...
 $ age.55.59  : num  126 129 235 125 149 108 179 137 175 106 ...
 $ age.60.64  : num  139 162 248 170 194 129 236 183 199 136 ...
 $ age.65.69  : num  110 110 205 95 129 143 172 128 167 130 ...
 $ age.70.74  : num  81 85 174 52 100 75 110 88 113 128 ...
 $ age.75.79  : num  78 54 130 58 74 70 72 68 119 114 ...
 $ age.80.84  : num  38 50 84 33 56 43 63 42 94 62 ...
 $ age.85.plus: num  39 55 50 27 48 42 36 55 85 84 ...

...using the following code:

foo <- merge(mydf, bar)

and plotted the result like this:

ggplot(foo, aes(x = long, y = lat, group = group)) + 
   geom_polygon(colour = "black", fill = "grey50")

The problem is that the resulting plot has artifacts as shown in the image below:

map with artifacts

So, the original data frame subset from the shapefile is fine, but the merged data file has 'issues'.

Q. What might be the cause of this kind of artifact? I understand that without the full code and data this is guesswork and I apologise in advance for this but the object is very large and there may also be redistribution issues. Any hints, pointers, suggestions as to where to start looking would be appreciated.

1
  • Rendering issues like this often come from geometry errors, though it's odd that they appear after merging the data frames. Try checking the errors in QGIS, or GRASS (which can also clean up errors for you).
    – Simbamangu
    Commented Oct 21, 2012 at 10:36

4 Answers 4

7

I have belatedly realised that the sort part of the merge call is to blame. If I use:

foo <- merge(mydf, bar, sort = FALSE)

The polygons plot correctly, at least in this particular case. Thanks to everybody for their input.

0
6

Compare the long, lat, piece, and hole columns of foo with those of bar. The merge has somehow lost that information.

The reason for the mess is usually that the polygons are made from more than one piece, and the algorithm draws each piece as separate rings. When the 'piece' info is missing it just draws the whole lot in one go. This reveals itself when there are either real islands or tiny digitising errors.

I think bar has one row per ring, but I guess the merge has produced one row per electoral division. Do the merge at the shapefile level, then fortify it.

3
  • Thanks for the suggestions, very helpful. Only problem is that I'm a complete newbie as regards shapefiles. Can you suggest how I should merge at the shapefile level? Commented Oct 21, 2012 at 14:44
  • 3
    When you read in the shapefile to a thing called shape back in your prev Q, you can treat that shape as a data frame (mostly). Add the column to that data frame. I'm not sure if merge will work, just get it in the right order and add it as new columns (cbind?). Then fortify and plot. In fact you can just use spplot(shape,"foo") and you don't need ggplot then.
    – Spacedman
    Commented Oct 21, 2012 at 14:49
  • Thanks, merge() is definitely messing something up in the piece column. I did a 'manual' merge and the polygons were fine. So I will have a think about how to tackle this, perhaps as you say adding data to the shapefile. Commented Oct 22, 2012 at 12:40
3

dplyr's left_join keeps all of the rows on the left (a) and joins b, adding all the columns from b. This way, none of the information from the data frame that contains the information about the polygons is changed. That might solve this problem.

The command would be:

library(dplyr)
foo <- left_join(mydf, bar)
2
  • Rather edit your old post then post it double. Think about the delete one of that posts.
    – wittich
    Commented Dec 3, 2015 at 18:18
  • You could make this a better answer by explaining what you think the problem is (in summary), and why your solution could solve that problem. Do you agree with the reason posted as a comment for example? If so you should say so and make a reference to it.
    – nmtoken
    Commented Dec 5, 2015 at 4:40
-2

Running foo<-foo[order(foo$order),] right after merging worked for me...Merge can mess up the ordering.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.