Problème boucle qui appelle une liste de base de données

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

Clement Corentin
Messages : 44
Enregistré le : 09 Aoû 2011, 08:55

Problème boucle qui appelle une liste de base de données

Messagepar Clement Corentin » 30 Nov 2017, 10:24

Bonjour à tous,

Je cherche à automatiser l'analyse d'une base de données. Pour cela je divise ma "méta base de donnée" en différentes bases de données par catégories de cultures et ensuite je groupe les noms de mes différentes bases de données dans une liste. Je fais cela avec le code suivant:

Code : Tout sélectionner

#Load data set
data <- as.data.frame(read.csv("~/UCPH/PLEN/Data/R input/Data/TRON_counting_Take_11_3.csv",sep=";",header=TRUE))

#Select column
Take11<-subset(data,select=c(id,intersection,distance,file.distance,depth.cm,grid.m,crop.sys))

#Create one database per crop type
id<-seq(1,40,1)
sous_df<-function(crop.sys,Take11){
  assign(paste("Crop_11",crop.sys,sep="_"),(Take11[Take11$crop.sys==crop.sys,]),envir = .GlobalEnv)
}
lapply(unique(Take11$crop.sys),sous_df,Take11) #applique la fonction sous_df à toutes les valeurs de ID pour le data.frame dta

# put the data.frames into a named list, where names correspond to data.frame names
myList <- mget(ls(pattern="^Crop_11"))
               
# fill in the column values
myList <- lapply(myList,function(i) within(i, rowNum <- seq_len(nrow(i))))


Ensuite sur chaque base de données j'aimerais calculer un indicateur en fonction des valeurs présentes dans la base de données (ligne: intersection/grid) et les regrouper en tranches de profondeur, pour cela j'essaye de faire tourner la boucle suivante mais R me renvoie "Error: Condition message must be a string"
Le code que j'utilise est le suivant:

Code : Tout sélectionner

tr_width <- 25
lapply(myList, function(df)

{
    t[i]<-df[i] %>%
    mutate(depth.cm_tr = -df$depth.cm %/% tr_width * tr_width) %>%  # crée les classes
    group_by(df$crop.sys,df$id,depth.cm_tr) %>%                     # groupes pour instuction suivante
    summarise(valeur = sum(df$intersection) / sum(df$grid.m)) %>%     # calcule l'indicateur
    spread(df$id,valeur, sep = "_")
    NULL
})


Est-ce quelqu'un aurais une idée du problème qu'il y a dans ma/mes lignes de code?
Aussi, une fois cela réalisé, j'aimerais faire tourner une autre boucle qui me permettrait de transformer mes bases de données t[i] du format "wide" au format "long" avec le code suivant:

Code : Tout sélectionner

  myList2 <- mget(ls(pattern="^t"))
  myList2 <- lapply(myList2,function(i) within(i, rowNum <- seq_len(nrow(i))))
 
  lapply(myList2, function(df)
  {
    data_long[i] <- gather(t[i],id,measurement,id_2:id_17, factor_key=TRUE)
    NULL
  })
 


Le problème est que le nom et nombre de colonnes (i.e.id_2:id_17 dans l'exemple ci-dessus) changes d'une base de données à l’autre (ex: id_24:id_56 dans le cas d'une autre base de données). Comment puis-je extraire le nom et nombre de colonnes de chaque bases de données afin de les référencer ensuite dans ma ligne de code?

Par avance, je vous remercie pour votre aide.
Corentin.

ps: Ps: J'ai recrée un post car le sujet me semblait un peu éloigné de ma question précédente

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Problème boucle qui appelle une liste de base de données

Messagepar Pierre-Yves Berrard » 30 Nov 2017, 11:15

Bonjour,

Je n'ai pas lu en détail, mais je vois plusieurs problèmes majeurs dans le deuxième bloc de code.

  • Que vaut i dans t[i]<-df[i] ?
  • L'utilisation sporadique du $ dans les fonctions de dplyr (mutate, summarise...). Pas besoin de le mettre en général.
  • NULL en dernière ligne sera la valeur retournée par la fonction, quelles que soient les lignes du dessus.

Deux questions sur l'algorithme en général :

  • Pourquoi séparer sa base en plusieurs sous-bases. Il doit être possible de faire les traitements sur la base principale.
  • Pourquoi faire un "spread" suivi d'un "gather", qui est le manipulation inverse ?
PY

Clement Corentin
Messages : 44
Enregistré le : 09 Aoû 2011, 08:55

Re: Problème boucle qui appelle une liste de base de données

Messagepar Clement Corentin » 30 Nov 2017, 11:40

Bonjour,

Petite clarification sur le code:

- "i" correspond a mon facteur "culture"
- Merci pour l'utilisation du $ dans dplyr, je note.
- J'ai lu qu'il fallait toujours finir la boucle par "NULL" mais cela doit être une erreur.

Pour les questions sur l’algorithme général, j’apprécie le fait d'avoir une table par culture, cela me permet de travailler sur des tables séparément au besoin même si cela ne paraît la méthode la plus simple et rapide. Plus modestement, j'essaye de faire avec les méthodes/moyens que je connais/maitrise sous R et j'en conviens le fais de faire un "spread" puis un "gather" ne me parait un peu comme une perte de temps mais jusqu'a présent je n'ai pas trouvé mieux.

Corentin.

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Problème boucle qui appelle une liste de base de données

Messagepar Pierre-Yves Berrard » 30 Nov 2017, 15:02

Clement Corentin a écrit :- "i" correspond a mon facteur "culture"
...
- J'ai lu qu'il fallait toujours finir la boucle par "NULL" mais cela doit être une erreur.


- En fait, peu importe ce que représente i (crop.sys ?). Comme il n'est jamais initialisé, ça ne peut pas marcher. Et même s'il était initialisé, ça risque de ne pas marcher non plus (pas de gestion d'indices dans lapply) ;
- Effectivement, il est inutile de finir une boucle par NULL. En plus, ici ce n'est pas une boucle mais une fonction, donc c'est non seulement inutile, mais donne un résultat faux.

Pouvez-vous vérifier que le code donné dans l'autre sujet fonctionne sur la base générale. Si vous voulez des données sous format long, vous enlevez juste le spread à la fin. Ensuite, vous pouvez utiliser la fonction sous_df (basée sur assign) pour stocker les tables dans l'environnement global ou la fonction split pour les stocker dans une liste.
PY


Retourner vers « Questions en cours »

Qui est en ligne

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