2017-07-26 21 views
3

j'aimerais générer une carte choroplèthe en utilisant les points de données suivants:Génération carte de chaleur spatiale par ggmap en R basée sur une valeur

  • Longitude
  • Latitude
  • Prix

Voici le jeu de données - https://www.dropbox.com/s/0s05cl34bko7ggm/sample_data.csv?dl=0.

Je voudrais la carte pour afficher les zones où le prix est plus élevé et le prix où est plus faible. Il devrait plus probablement ressembler à ceci (exemple d'image):

enter image description here

Voici mon code:

library(ggmap) 

map <- get_map(location = "austin", zoom = 9) 
data <- read.csv(file.choose(), stringsAsFactors = FALSE) 
data$average_rate_per_night <- as.numeric(gsub("[\\$,]", "", 
data$average_rate_per_night)) 
ggmap(map, extent = "device") + 
stat_contour(data = data, geom="polygon", 
      aes(x = longitude, y = latitude, z = average_rate_per_night, 
fill = ..level..)) + 
scale_fill_continuous(name = "Price", low = "yellow", high = "red") 

Je reçois le message d'erreur suivant:

2: Computation failed in `stat_contour()`: 
Contour requires single `z` at each combination of `x` and `y`. 

I J'apprécie vraiment toute aide sur la façon dont cela peut être réparé ou toute autre méthode pour générer ce type de heatmap. S'il vous plaît noter que je suis intéressé dans le poids du prix, pas la densité des dossiers.

+0

Etes-vous sûr que vous êtes à la recherche d'un choroplèthes? Autant que je sache, la plupart des choroplèthes utilisent des régions administratives, et non des lattitudes/longitudes. –

+0

Je suis d'accord. Je pense que le terme correct devrait être une carte de contour. – user709413

+0

J'ai été capable de me débarrasser du message d'erreur 'single z à chaque combinaison' en faisant la moyenne des taux par nuit (certaines combinaisons x et y avaient plusieurs taux moyens, je suppose en raison de l'arrondissement des coordonnées). Mais le contour n'a toujours pas dessiné.Je ne sais pas pourquoi et il n'a pas dit. Le tracé de lignes de contour fonctionne pour les rasters, vous pouvez donc le faire fonctionner en changeant la trame de données en raster et en remplaçant les valeurs manquantes. J'abandonne pour l'instant ... –

Répondre

2

Si vous insistez sur l'utilisation de l'approche de contour, vous devez fournir une valeur pour tous les x possibles, y coordonnées combinaison que vous avez dans vos données. Pour ce faire, je recommande fortement de quadriller l'espace et générer des statistiques récapitulatives par poubelle.

Je joins un exemple de travail ci-dessous en fonction des données que vous avez fournies:

library(ggmap) 
library(data.table) 

map <- get_map(location = "austin", zoom = 12) 
data <- setDT(read.csv(file.choose(), stringsAsFactors = FALSE)) 

# convert the rate from string into numbers 
data[, average_rate_per_night := as.numeric(gsub(",", "", 
     substr(average_rate_per_night, 2, nchar(average_rate_per_night))))] 

# generate bins for the x, y coordinates 
xbreaks <- seq(floor(min(data$latitude)), ceiling(max(data$latitude)), by = 0.01) 
ybreaks <- seq(floor(min(data$longitude)), ceiling(max(data$longitude)), by = 0.01) 

# allocate the data points into the bins 
data$latbin <- xbreaks[cut(data$latitude, breaks = xbreaks, labels=F)] 
data$longbin <- ybreaks[cut(data$longitude, breaks = ybreaks, labels=F)] 

# Summarise the data for each bin 
datamat <- data[, list(average_rate_per_night = mean(average_rate_per_night)), 
       by = c("latbin", "longbin")] 

# Merge the summarised data with all possible x, y coordinate combinations to get 
# a value for every bin 
datamat <- merge(setDT(expand.grid(latbin = xbreaks, longbin = ybreaks)), datamat, 
       by = c("latbin", "longbin"), all.x = TRUE, all.y = FALSE) 

# Fill up the empty bins 0 to smooth the contour plot 
datamat[is.na(average_rate_per_night), ]$average_rate_per_night <- 0 

# Plot the contours 
ggmap(map, extent = "device") + 
    stat_contour(data = datamat, aes(x = longbin, y = latbin, z = average_rate_per_night, 
       fill = ..level.., alpha = ..level..), geom = 'polygon', binwidth = 100) + 
    scale_fill_gradient(name = "Price", low = "green", high = "red") + 
    guides(alpha = FALSE) 

enter image description here

Vous pouvez ensuite jouer avec la taille du bac et le contour binwidth pour obtenir le résultat souhaité, mais Vous pouvez également appliquer une fonction de lissage sur la grille pour obtenir un tracé de contour encore plus lisse.

+0

Cela fonctionne bien. Je vais jouer avec 'binwidth' et la taille de la poubelle. – user709413

+0

J'ai une question - ne devrions-nous pas prendre xbreaks et ybreaks comme longitude et latitude? Pourriez-vous s'il vous plaît expliquer? – user709413

+1

Vous pouvez mais vos données ne couvrent pas uniformément toute la zone. Cela signifie que vous finirez par avoir des godets de tailles inégales et que le tracé de contour peut ne pas être aussi lisse que dans l'exemple. De plus, en utilisant l'approche proposée, vous vous assurez que vous fournissez les données de tracé de contour pour toutes les combinaisons x, y. – gcons

0

Vous pouvez utiliser le stat_summary_2d() ou stat_summary_hex() fonction pour obtenir un résultat similaire. Ces fonctions diviser les données en bacs (définis par x et y), et ensuite les valeurs de z pour chaque bac sont résumés sur la base d'une fonction donnée. Dans l'exemple ci-dessous, j'ai choisi en moyenne une fonction d'agrégation et la carte montre essentiellement le prix moyen dans chaque bac.

Note: J'avais besoin de traiter votre variable average_rate_per_night de manière appropriée afin de le convertir en nombres (enlevé le signe $ et la virgule).

library(ggmap) 
library(data.table) 

map <- get_map(location = "austin", zoom = 12) 
data <- setDT(read.csv(file.choose(), stringsAsFactors = FALSE)) 
data[, average_rate_per_night := as.numeric(gsub(",", "", 
    substr(average_rate_per_night, 2, nchar(average_rate_per_night))))] 

ggmap(map, extent = "device") + 
    stat_summary_2d(data = data, aes(x = longitude, y = latitude, 
     z = average_rate_per_night), fun = mean, alpha = 0.6, bins = 30) + 
    scale_fill_gradient(name = "Price", low = "green", high = "red") 

enter image description here

+0

Merci pour l'aide, mais je cherche quelque chose comme ça - https://sromalewski.files.wordpress.com/2011/09/bike-share-station-suggestions-091911- 913x1024.png – user709413