Creation d'une variable dans une boucle ...?

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

marlyse clement
Messages : 7
Enregistré le : 27 Oct 2021, 17:25

Creation d'une variable dans une boucle ...?

Messagepar marlyse clement » 30 Oct 2021, 18:11

Bonjour à tous,
Ceci est mon premier message et j'essaye de respecter toutes les consignes.
Merci de me dire si c'est ok ! ;)

EDIT [21h]: J'ai oublie de mettre les "library"
Voici la liste , je ne sais pas si elles sont toutes utile pour le code ci dessous... (J'ai quand meme supprimer celle que j'ai dont je suis sur qu'elle ne sont pas utiliser par cela ici.

Code : Tout sélectionner

library(downloader)
library(sf)
library(DT)
library(tidyverse)
library(readxl)
library(readr)
library(dplyr)
library(sp)
library(curl)
library(httr)
library(readxl)



Partie du code qui marche (et qui sert a faire un code reproductible). Les commentaires présents sont aussi pour moi pour améliorer plus tard le script... ^^

Creation des variables

Code : Tout sélectionner

SNCF_Sous_station = "https://ressources.data.sncf.com/explore/dataset/liste-des-sous-stations/download/?format=shp&timezone=Europe/Berlin&lang=fr"
SNCF_Triage = "https://data.sncf.com/explore/dataset/liste-des-triages/download/?format=shp&timezone=Europe/Berlin&lang=fr"
SNCF_Livraison = "https://ressources.data.sncf.com/explore/dataset/sites-de-livraison-sncf-ti-geoparts-v2/download/?format=shp&timezone=Europe/Berlin&lang=fr"


Ici les tables sont dans des fichiers ZIP donc j'ai trouve "un protocole" pour les importer ^^
Import des tables

Code : Tout sélectionner

#SousStationSNCF
temp <- tempfile()
temp2 <- tempfile()
#telecharger le zip depuis internet, sauvegarder dans temp
download.file(SNCF_Sous_station,temp, mode="wb")

#Dezipper le fichier temps et enregistrer les resources déziper dans temp2
unzip(zipfile = temp, exdir = temp2)
#recuperer le chemin d'accès du the shapefile (.shp) file dans le fichieer deziper temp2
#le $ à la fin de  ".shp$" assure de ne pas trouver des fichier du style .shp.xml
SousstationSNCF_shpelink<-list.files(temp2, pattern = ".shp$",full.names=TRUE)

#read the shapefile. Alternatively make an assignment, such as f<-sf::read_sf(your_SHP_file)
SousStation_SNCF <-sf::read_sf(SousstationSNCF_shpelink) %>%
  st_transform(4326) # safety of unprojected CRS


#Livraison SNCF
temp <- tempfile()
temp2 <- tempfile()
#telecharger le zip depuis internet, sauvegarder dans temp
download.file(SNCF_Livraison,temp, mode="wb")

#Dezipper le fichier temps et enregistrer les resources déziper dans temp2
unzip(zipfile = temp, exdir = temp2)
#recuperer le chemin d'accès du the shapefile (.shp) file dans le fichieer deziper temp2
#le $ à la fin de  ".shp$" assure de ne pas trouver des fichier du style .shp.xml
LivraisonSNCF_shpelink<-list.files(temp2, pattern = ".shp$",full.names=TRUE)

#read the shapefile. Alternatively make an assignment, such as f<-sf::read_sf(your_SHP_file)
Livraison_SNCF <-sf::read_sf(LivraisonSNCF_shpelink) %>%
  st_transform(4326) # safety of unprojected CRS


#Triage SNCF
temp <- tempfile()
temp2 <- tempfile()
#telecharger le zip depuis internet, sauvegarder dans temp
download.file(SNCF_Triage,temp, mode="wb")

#Dezipper le fichier temps et enregistrer les resources déziper dans temp2
unzip(zipfile = temp, exdir = temp2)
#recuperer le chemin d'accès du the shapefile (.shp) file dans le fichieer deziper temp2
#le $ à la fin de  ".shp$" assure de ne pas trouver des fichier du style .shp.xml
TriageSNCF_shpelink<-list.files(temp2, pattern = ".shp$",full.names=TRUE)

#read the shapefile. Alternatively make an assignment, such as f<-sf::read_sf(your_SHP_file)
Triage_SNCF <-sf::read_sf(TriageSNCF_shpelink) %>%
  st_transform(4326) # safety of unprojected CRS
 
  #suprression des fichiers intermediaires
  remove(TriageSNCF_shpelink,LivraisonSNCF_shpelink,SousstationSNCF_shpelink)
  remove(SNCF_Sous_station, SNCF_Triage, SNCF_Livraison)


Traitement des tables

Code : Tout sélectionner

#creation d'une liste avec un critère de nom
sncf_list = mget(ls(pattern = ("SNCF$")))
#Cette manipulation est a lancé qu'une fois sinon elle rajouter des doublons à chaque fois....
#le dollar precise que les caractères SNCF sont les dernier à prendre en compte, comme pour l'import shape


Code : Tout sélectionner

#Creation de la source
Liste_SNCF_Source <- lapply(sncf_list, function(x){
  x$source<- "SNCF"
  return(x)
})


C’est la que ca se gatte, je souhaiterais automatiser la création d’une variable « table » qui pour chaque table de la liste épendrait du nom de celle ci. Par exemple pour la table de provenance « Livraison_SNCF » celle ci aurait comme nom « Livraison ».

J’ai bien sur d’autre source, et d’autre tables pour lequel je repetterais le processus du code.
Pour les plus petit groupe (2 a 5 table) j’écris pour l’instant en dur, pour chaque table, mais j'avoue que quand ca dépasse les 5 ca me soule un peu.... sans compter que le code devient TRES long. Et comme la liste est creer "automatiquement" a partir d'un bout du nom je ne sais pas dans quel ordre il les ajoute...

Code : Tout sélectionner

Livraison_SNCF = as.data.frame(list(Liste_SNCF_Source[[1]]))
  Livraison_SNCF$table = "Livraison"

SousStation_SNCF = as.data.frame(list(Liste_SNCF_Ssource[[2]]))
  SousStation_SNCF$table = "SousStation"

Triage_SNCF = as.data.frame(list(Liste_SNCF_Source[[3]]))
  Triage_SNCF$table = "Triage"



Je termine par remttre les elements de la liste dans l'environnement

Code : Tout sélectionner

#list2env(Liste_SNCF_Source, .GlobalEnv) pour l'instant creation des tables pour les variables de table donc non !
remove(Liste_SNCF_Source)





Voici les codes de la boucle for que j'ai testé

Methode 1

Code : Tout sélectionner

for (i in seq(Liste_SNCF_Source)) {
lapply(sncf_list, function(x){
  x$table<- "[[i]]"
 
  function(x) {x$table <- "[[i]]"
  }
}


Methode 2

Code : Tout sélectionner

Pas de message d’erreur mais ca ne me créer pas la variable que je souhaite.

Methode 2
for (i in seq(Liste_SNCF_Source)) {
  lapply(Liste_SNCF_Source, function(x){
    x$table<- "[[i]]"
    return(x)    }
  ) 
}


Pour ces deux methodes : pas de message d'erreur mais pas non plus de variables adéquates creer....

Methode 3 : Mon i étant pas un numero j’ai essayé mais sans i croire.

Code : Tout sélectionner

for (i in seq(Liste_SNCF_Source)) {
  i$table = as.character(i)
}


Error in as.character[i] : objet de type 'builtin' non indiçable


J'ai peut etre mal compris le principe de la boucle for , mais pour moi c'est pour i de 1 a x (nombre donnée ou déterminer par la liste) faire
creation d'une variable = nom de la table en caractère
Mais est ce possible ?

PS : je suis consciente que mon message est très long mais j'espère qu'il ne vous rebuttera pas pour m'aider. Merci d'avance !

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Creation d'une variable dans une boucle ...?

Messagepar Mickael Canouil » 01 Nov 2021, 19:01

Bonjour,

je n'ai pas bien compris l'objectif, le résultat souhaité.

Code : Tout sélectionner

library(utils)
library(sf)

sncf <- c(
  
SNCF_Sous_station "liste-des-sous-stations",
  
SNCF_Triage "liste-des-triages",
  
SNCF_Livraison "sites-de-livraison-sncf-ti-geoparts-v2"
)

get_sncf_data <- function(table) {
  
base_url <- paste0(
    
"https://ressources.data.sncf.com/explore/dataset/",
    
table,
    
"/download/?format=shp&timezone=Europe/Berlin&lang=fr"
  
)

  
temp <- tempfile(fileext ".zip")
  
on.exit(unlink(temp))
  
utils::download.file(base_urltempmode "wb")
  
shape_file <- grep("\\.shp$"utils::unzip(temp, list = TRUE)[["Name"]], value TRUE)
  
utils::unzip(
    
zipfile temp,
    
files shape_file,
    
exdir "."# default
    
overwrite TRUE
  
)

  
sf::st_transform(sf::read_sf(shape_file), 4326)
}

res <- lapply(sncfget_sncf_data


"res" sera une liste nommée contenant les shapefile lus.
J'aurai tendance à m'arrêter sur la structure de liste que l'on peut naviguer via des lapply par exemple.

Si l'idée est d'avoir accès aux variables via leur nom dans l'environnement, un attach(res) donnera le résultat escompté (qu'on pourra annulé par un "detach(res)").

Exemple reproductible sans "sf" qui ne fonctionne pas chez moi sur les fichiers en questions :

Code : Tout sélectionner

library(utils)
library(sf)
#> Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1

sncf <- c(
  
SNCF_Sous_station "liste-des-sous-stations",
  
SNCF_Triage "liste-des-triages",
  
SNCF_Livraison "sites-de-livraison-sncf-ti-geoparts-v2"
)
get_sncf_data <- function(table) {
  
base_url <- paste0(
    
"https://ressources.data.sncf.com/explore/dataset/",
    
table,
    
"/download/?format=shp&timezone=Europe/Berlin&lang=fr"
  
)

  
temp <- tempfile(fileext ".zip")
  
on.exit(unlink(temp))
  
utils::download.file(base_urltempmode "wb")
  
shape_file <- grep("\\.shp$"utils::unzip(temp, list = TRUE)[["Name"]], value TRUE)
  
utils::unzip(
    
zipfile temp,
    
files shape_file,
    
exdir "."# default
    
overwrite TRUE
  
)

  
shape_file
  
# sf::st_transform(sf::read_sf(shape_file), 4326)
}

res <- lapply(sncfget_sncf_data)
attach(res)
SNCF_Livraison
#> [1] "sites-de-livraison-sncf-ti-geoparts-v2.shp" 


Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

marlyse clement
Messages : 7
Enregistré le : 27 Oct 2021, 17:25

Re: Creation d'une variable dans une boucle ...?

Messagepar marlyse clement » 01 Nov 2021, 19:52

Bonjour ,
Merci beaucoup pour cette première réponse !
Je n'ai pas encore tester dans R. En effet je suis en congé.... ^^

Mon objectif a la fin , vu que je vais regroupe toute les tables à la fin, je veux avoir une colonne (variable) source et une variable "table" pour connaitre la table d'oigine.
Ici (mais j'ai d'autre source : Apur, IAU, Insee ...) les trois tables auront comme variable source "SNCF", et table "Livraison" ou "Triage" ou "Sous station".

Comme ca quand j'aurais ma base avec la totalité des tables et des sources je pourrais savoir dans quel thematique est chacune de mes observations. :)

Dans l'ideal (c'est prevu comme ca) l'exploitation sera aussi "geographique" : equipement par ville ...

Est ce que cela est plus clair ?

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Creation d'une variable dans une boucle ...?

Messagepar Mickael Canouil » 02 Nov 2021, 11:31

Vous souhaitez combiner les tables, mais comment ? Concaténation (rbind) ? Jointure (merge) ?

Code : Tout sélectionner

do.call("rbind", res

Code : Tout sélectionner

data.table::rbindlist(res,  idcol = "source")

Code : Tout sélectionner

Reduce(merge, res)
Mickaël
mickael.canouil.fr | rlille.fr

marlyse clement
Messages : 7
Enregistré le : 27 Oct 2021, 17:25

Re: Creation d'une variable dans une boucle ...?

Messagepar marlyse clement » 08 Nov 2021, 09:36

Merci beaucoup !

Je pensais faire des concatenations :)
Mais d'abord faut que je "nettois" dans les autres tables ce qui m'interesse !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité