Intro

Quelle est la meilleure ville pour s’installer en dehors de Paris ? Chacun a sa meilleure réponse, basée sur un certain nombre de critères comme la météo, l’emploi, l’éloignement, le coût de la vie, …

Je propose dans cet essai d’aller récupérer ces données et de les visualiser.

Quelles sont les plus grandes villes de France ?

Nous allons utiliser Wikidata pour récupérer les 20 plus grandes villes de France, puis nettoyer les coordonnées pour pouvoir les utiliser par la suite. On obtient le tableau ci-dessous (Paris est enregistrée séparément). Pour voir les fonctions utilisées, vous pouvez retrouver le fichier sur le repo.

source("getCities.R")
cities <- getCities(2,21)
paris <- getCities(1,1)
kable(cities[1:6,-3],format="markdown")
cityLabel population lon lat
2 Marseille 855393 5.376389 43.29667
3 Lyon 506615 4.841389 45.75889
4 Toulouse 471941 1.443889 43.60444
5 Nice 342522 7.268333 43.70194
6 Nantes 303382 -1.553889 47.21722
7 Strasbourg 279284 7.752222 48.57333

Soit, visuellement en utilisant le package leaflet.

francemap <- leaflet() %>%
    addTiles() %>%
    addMarkers(lng = cities$lon, lat = cities$lat, popup = cities$cityLabel)
francemap

Score

Ajoutons maintenant une colonne de score, qui prendra en compte les différents critères calculés. L’avantage sera de pouvoir faire évoluer la pondération des critères dans le score. Pour l’instant, le score sera de 100 pour la meilleure ville et de 0 pour la moins bonne. Ce calcul devra évoluer par la suite, la fonction pourra prendre des paramètres en option.

source("getScore.R")
cities$populationScore <- getScore(cities$population)
cities$score <- cities$populationScore
francemap <- leaflet() %>%
    addTiles() %>%
    addCircleMarkers(lng = cities$lon, lat = cities$lat, radius = cities$score/2, label = cities$cityLabel)
francemap

Critère de distance

Nous allons commencer par calculer les distances entre chacune de ces villes et Paris. Nous commencerons par des distances à vol d’oiseau. Le contenu de la function straightDistance() est disponible dans le repo.

Dans le calcul du score, cette fois-ci un petit nombre est un bon score, il faut le prendre en compte dans nos calculs

source("straightDistance.R")
distanceToParis <- vector()
for (i in 1:length(cities[,1])){
    distanceToParis[i] <- straightDistance(cities$lon[i],cities$lat[i],paris$lon,paris$lat)
}
cities <- cbind(cities,distanceToParis)
cities$distanceScore <- 100-getScore(cities$distanceToParis)
cities$score <- (cities$populationScore+cities$distanceScore)/2
francemap <- leaflet() %>%
    addTiles() %>%
    addCircleMarkers(lng = cities$lon, lat = cities$lat, radius = cities$score/2, label = cities$cityLabel)
francemap
kable(cities[1:6,c(1,6)], format = "markdown")
cityLabel populationScore
2 Marseille 121.03567
3 Lyon 71.68458
4 Toulouse 66.77831
5 Nice 48.46589
6 Nantes 42.92769
7 Strasbourg 39.51789

Critère d’activité culturelle

On trouve sur data.gouv.fr un agenda de l’offre culturelle par ville (https://www.data.gouv.fr/s/resources/agenda-de-l-offre-culturelle/community/20150724-153623/Agenda24072015.csv). Malheureusement, ces données datent de 2015 et il n’y a pas de jeu de données plus récent. Récupérons le nombre d’événements culturels.

Le lieu dans ce fichier est précisé en latitude/longitude. Il serait intéressant d’obtenir le nombre d’événements culturels dans un rayon de 10km plutôt que purement dans la ville. Malheureusement, cette donnée n’est présente que dans moins de 10% des cas.
Nous pourrions utiliser une fonction de geocoding pour récupérer les coordonnées de chaque ville hébergeant chaque événement. Nous avons 34000 adresses à géocoder, ce qui reste dans les limites d’usage de l’API Google : [https://developers.google.com/maps/documentation/geocoding/usage-and-billing]. Il faut néanmoins donner ses coordonnées CB, ce que je ne suis pas prêt à faire. Nous utiliserons une alternative : le geocoder de Data Science Toolkit [http://www.datasciencetoolkit.org/]

La fonction getCulture() va calculer pour chaque point du calendrier de l’offre culturelle, si il est dans le rayon de chaque ville. Puis il additionnera le nombre de lignes trouvées pour chaque ville.
Nous allons pouvoir réutiliser la fonction de calcul de distances.

cultureAgendaLink <- "https://www.data.gouv.fr/s/resources/agenda-de-l-offre-culturelle/community/20150724-153623/Agenda24072015.csv"
source("getCultureEvents.R")
events <- getCultureEvents(cultureAgendaLink,cities)
kable(events[1:6], format = "markdown")
x
Marseille 60
Lyon 48
Toulouse 842
Nice 593
Nantes 234
Strasbourg 525

Les disparités sont (beaucoup trop) fortes, la source de l’agenda culturel n’est probablement pas la meilleure pour ce que nous cherchons à obtenir. data.gouv.fr a probablement autre chose à nous proposer pour compenser.
Explorons la piste des musées, ce fichier contient 1250 lignes : https://www.data.gouv.fr/fr/datasets/r/22df4a13-72d8-4b34-940e-8aec297b5ded. Il faudra ici parser un fichier .xlsx, calculer les coordonnées gps puis les distances par rapport à la liste des villes.
On se rend compte qu’une partie du code pourrait être factorisé.

museumsSourceLink <- "https://www.data.gouv.fr/fr/datasets/r/22df4a13-72d8-4b34-940e-8aec297b5ded"
source("getMuseums.R")
cities$museums <- getMuseums(museumsSourceLink,cities)
cities$culturalScore <- getScore(cities$museums)
cities$score <- (cities$populationScore+cities$distanceScore+cities$culturalScore)/3
francemap <- leaflet() %>%
    addTiles() %>%
    addCircleMarkers(lng = cities$lon, lat = cities$lat, radius = cities$score/2, label = cities$cityLabel)
francemap

Critère d’emploi

Essayons maintenant de voir quelle ville a le meilleur potentiel pour trouver du travail. Nous allons scrapper le site indeed pour obtenir le nombre d’offres en ligne sur chacune de nos villes.

source("getjobs.R")
cities$jobs <- getJobs(cities)
cities$jobScore <- getScore(cities$jobs)
cities$score <- (cities$populationScore+cities$distanceScore+cities$culturalScore+cities$jobScore)/4
francemap <- leaflet() %>%
    addTiles() %>%
    addCircleMarkers(lng = cities$lon, lat = cities$lat, radius = cities$score/2, label = cities$cityLabel)
francemap

Visualisation interactive

Il pourrait être intéressant de visualiser l’effet de chacun des scores en “temps réel”, pour permettre à chacun de pondérer chaque critère selon ses envies. Une application Shiny s’alimentant sur les données que l’on a récupérées.
Nous allons simplement enregistrer les données dans le répertoire de l’application Shiny pour qu’elles puissent être réutilisées.

save(cities,file="./shinyapp/outside-paris/cities.Rdata")

L’application est visible ici : https://paul-chrlt.shinyapps.io/outside-paris/

Finalement, ca donne envie de créer la même chose sous forme de carte de chaleur, pour avoir cette vision de facon plus universelle.