Duncan Temple Lang

University of California at Davis

Department of Statistics


This example illustrates how we can color the placemark icons. We will use the housing data again. We put placemarks for some of the houses, specifically in the city of Mill Valley We color them based on the house price. We create a categorical variable representing house price using cut() . Then we create icons for these different levels.

load("~/Data/housing.Rda")
mv = subset(housing, city == "Mill Valley")

We check that there are sufficiently many observations and range to make things somewhat interesting:

dim(mv)
range(mv$price, na.rm = TRUE)

Let's create a categorical price variable:

mv$priceLevel = cut(mv$price, 7)

We look at the distribution of these

table(mv$priceLevel)

We might want to specify the breaks directly:

mv$priceLevel = cut(mv$price, c(0, 3e5, 6e5, 9e5, 1.2e6, 1.5e6, 2e6, max(mv$price, na.rm = TRUE)))

Now let's create icons for the 7 different levels.

library(RKML)
icons = mapply(makeBall, heat.colors(7), sprintf("heat_%d.png", 1:7))

styles = lapply(icons, function(x) list(IconStyle = list(scale = ".5", Icon = c(href = x))))
names(styles) = gsub(".png", "", icons)

doc = kmlPoints(.longitude = mv$long, .latitude = mv$lat, .names = rep("", nrow(mv)), # .names = as.character(mv$street),
                folderName = "Mill Valley",
                styles = styles,
                col = names(styles)[mv$priceLevel])

Note that we turn off the names appearing on the display so that we can see the colors clearly.

saveXML(doc, "millValleyByColor.kml")

Glyphs

We can also use color and glyphs to represent two additional variables. Let's look at the distribution of priceLevel and number of bedrooms:

with(mv, table(priceLevel, br))

We want a collection of icons that have color corresponding to priceLevel and a glyph or plotting character corresponding to number of bedrooms. In R, we can specify these independently. In KML, we need to create these icons and the refer to them as styles. So let's create icons for all possible combinations of priceLevel and br. (Of course, we only need the ones for which there is at least one observation.) We want to use plotting characters which are solid, i.e. filled in. These are 15:20. We can also use 8 and 10. The others are a little to sparse of color and so are not very visible with the terrain underneath them.

pairs = expand.grid(seq(along = levels(mv$priceLevel)), unique(mv$br))
colors = heat.colors(length(levels(mv$priceLevel)))
pch = c(8, 10, 15:20)
icons = apply(pairs, 1, 
               function(x) 
                 makePchIcon( pch[ x[2] ], colors[ x[1] ], sprintf("icon_%d_%d.png", x[1], x[2])))

So now we turn these into a form to define styles for our document:

styles = lapply(icons, function(x) list(IconStyle = list(scale = ".5", Icon = c(href = x))))
names(styles) = gsub(".png", "", icons)

And now we can use these

idx = sprintf("icon_%d_%d", as.integer(mv$priceLevel), as.integer(mv$br))
doc = kmlPoints(.longitude = mv$long,
                .latitude = mv$lat, 
                .names = rep("", nrow(mv)),
                folderName = "Mill Valley",
                styles = styles,
                col = names(styles[idx]))

saveXML(doc, "millValleyBrPrice.kml")

Of course another approach is to put the houses with the same number of bedrooms in their own folder.