I'm working on a primitive shiny app that would map some data from the Open Data for Scotland project. I worked out the SPARQL queries that manufacture a data frame resembling the extract provided below
dz_label overall.quantiles
S010001 8
S010002 9
I have the fortified shapefiles and I'm trying to map them with use of the following code:
ggplot() +
geom_map(data = dta.simd, aes(map_id = dz_label,
fill = as.factor(dta.simd$overall.quantiles)),
map = shps.dzs2001) +
geom_path(data = shps.dzs2001, aes(x=long, y=lat, group=group),
colour="black", size=0.25)
The code returns the error
Error: 'x' and 'units' must have length > 0
If I understand similar discussions (1, 2), the problem is associated with the value classes. However, my understanding is that the as.factor()
should address this but, evidently this is not the case. The full code for the app is included below. Naturally, I'll be grateful for any help.
Server
# Libs
require(shiny); require(SPARQL); require(ggplot2); require(rgeos); require(maptools);
require(RCurl)
# Server function
shinyServer(function(input, output) {
# Source the data
## Source the SPARQL data
### Define endpoint URL.
endpoint <- "http://data.opendatascotland.org/sparql.csv"
### Create Query and download table for the SIMD rank
query.simd <- "PREFIX stats: <http://statistics.data.gov.uk/id/statistical-geography/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX simd: <http://data.opendatascotland.org/def/simd/>
PREFIX cube: <http://purl.org/linked-data/cube#>
PREFIX stats_dim: <http://data.opendatascotland.org/def/statistical-dimensions/>
PREFIX year: <http://reference.data.gov.uk/id/year/>
SELECT DISTINCT
?dz_label
?overall_rank
?income_deprivation_rank
?employment_deprivation_rank
?health_deprivation_rank
?education_deprivation_rank
?access_deprivation_rank
?housing_deprivation_rank
?crime_deprivation_rank
WHERE {
GRAPH <http://data.opendatascotland.org/graph/simd/rank> {
?overall_rank_observation stats_dim:refArea ?dz .
?overall_rank_observation stats_dim:refPeriod year:2012 .
?overall_rank_observation simd:rank ?overall_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/income-rank> {
?income_rank_observation stats_dim:refArea ?dz .
?income_rank_observation stats_dim:refPeriod year:2012 .
?income_rank_observation simd:incomeRank ?income_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/employment-rank> {
?employment_rank_observation stats_dim:refArea ?dz .
?employment_rank_observation stats_dim:refPeriod year:2012 .
?employment_rank_observation simd:employmentRank ?employment_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/health-rank> {
?health_rank_observation stats_dim:refArea ?dz .
?health_rank_observation stats_dim:refPeriod year:2012 .
?health_rank_observation simd:healthRank ?health_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/education-rank> {
?education_rank_observation stats_dim:refArea ?dz .
?education_rank_observation stats_dim:refPeriod year:2012 .
?education_rank_observation simd:educationRank ?education_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/geographic-access-rank> {
?access_rank_observation stats_dim:refArea ?dz .
?access_rank_observation stats_dim:refPeriod year:2012 .
?access_rank_observation simd:geographicAccessRank ?access_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/housing-rank> {
?housing_rank_observation stats_dim:refArea ?dz .
?housing_rank_observation stats_dim:refPeriod year:2012 .
?housing_rank_observation simd:housingRank ?housing_deprivation_rank .
}
GRAPH <http://data.opendatascotland.org/graph/simd/crime-rank> {
?crime_rank_observation stats_dim:refArea ?dz .
?crime_rank_observation stats_dim:refPeriod year:2012 .
?crime_rank_observation simd:crimeRank ?crime_deprivation_rank .
}
{
SELECT ?dz ?dz_label WHERE
{
?dz a <http://data.opendatascotland.org/def/geography/DataZone> .
?dz rdfs:label ?dz_label .
}
}
}"
## Make the data table for SIMD
dta.simd <- SPARQL(url = endpoint, query = query.simd, format = "csv")$results
### Clean the data frame
dta.simd$dz_label <- gsub("Data Zone","", dta.simd$dz_label)
# Readings shapefiles (pass only file that ends with shp)
shps.dzs2001 <- readShapeSpatial("data/SG_DataZone_Bdry_2001.shp")
## Read shapefiles
shps.dzs2001 <- fortify(shps.dzs2001, region= "DZ_CODE")
# Switch on the gclibpermit
gpclibPermit()
# Make the plot
output$distPlot <- renderPlot({
### Get the column index fumber
col.ind <- match(input$firstvar, colnames(dta.simd))
#### Calculate the breaks
##### Take tha quantilies value from the UI
##### Obtain the breaks
dta.simd$column <- as.numeric(as.character(dta.simd[,col.ind]))
dta.simd$overall.quantiles <- ceiling(sapply(dta.simd$column,function(x)
sum(x-dta.simd$column>=0))/(length(dta.simd$column)/input$quannum))
#### Graph the chart
ggplot() +
geom_map(data = dta.simd, aes(map_id = dz_label,
fill = as.factor(dta.simd$overall.quantiles)),
map = shps.dzs2001) +
geom_path(data = shps.dzs2001, aes(x=long, y=lat, group=group),
colour="black", size=0.25)
### Re-calculate summary stats
summary.data <- head(dta.simd)
})
### Do the summary tables
output$summary.table <- renderDataTable({summary.data})
})
UI
require(shiny)
# Define list of options
choices.list <- list("Overall Rank" = "overall_rank",
"Income" = "income_deprivation_rank",
"Employment" = "employment_deprivation_rank",
"Health" = "health_deprivation_rank",
"Education" = "education_deprivation_rank",
"Access to Services" = "access_deprivation_rank",
"Housing" = "housing_deprivation_rank",
"Crime" = "crime_deprivation_rank"
)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Scottish Index of Multiple Deprivation 2012"),
# Sidebar with a slider input for the number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "firstvar",
label = "Index domain to map",
choices = choices.list,
selected = "income_deprivation_rank"),
sliderInput("quannum", label = "Number of quantiles",
min = 0,
max = 100,
value = 10)),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot", height = "700px"),
dataTableOutput("summary.data"),
h5("Notes"),
p("The data is sourced live from the Open Data for Scotland Project. The shapefiles are sourced from the Scottish Neighbourhood Statistics.")
)
)
))
fill=factor(overall.quantiles)
I was facing a similar problem and was able to fix it this way.