Créer une liste de data frames à partir des individus d'un data frame

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

Fabien Pille
Messages : 2
Enregistré le : 05 Juil 2016, 08:06

Créer une liste de data frames à partir des individus d'un data frame

Messagepar Fabien Pille » 06 Avr 2019, 10:21

Bonjour,

Je dispose d'un data frame dans lequel chaque ligne correspond à une localisation dans l'espace (x, y) pour un individu (ID). Il existe plusieurs localisations (point) par individu à la suite dans le data frame. Ci dessous, un exemple avec deux individus ayant chacun deux localisations :

Code : Tout sélectionner

> df
       ID Point   x  y
1 C1_Pf_F     1 272 50
2 C1_Pf_F     2 260 44
3 C2_Pf_S     1 245 21
4 C2_Pf_S     2 236 19


Je souhaite créer un data frame par individu ET stocker tous les data frames obtenus dans une liste de manière automatique (j'ai en réalité plus de 100 individus).

Je suis parvenu à créer un data frame par un individu grâce à la fonction "for" :

Code : Tout sélectionner

for(i in unique(df$ID)) {
        nam <- paste("df", i, sep = ".")
        assign(nam, df[df$ID==i,])
        }


Cependant, je ne parviens par à stocker les data frame créés dans une liste. Une idée de la façon dont je dois procéder?

Merci par avance.

Fabien

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

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Pierre-Yves Berrard » 06 Avr 2019, 11:59

Bonjour,

Code : Tout sélectionner

liste_df <- split(df, df$ID)
PY

Fabien Pille
Messages : 2
Enregistré le : 05 Juil 2016, 08:06

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Fabien Pille » 07 Avr 2019, 08:56

Bonjour,

Merci beaucoup !

Fabien

Anais Payen
Messages : 60
Enregistré le : 25 Fév 2019, 08:50

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Anais Payen » 11 Avr 2019, 12:32

Pierre-Yves Berrard a écrit :Bonjour,

Code : Tout sélectionner

liste_df <- split(df, df$ID)


J'avais retenu cette réponse pour faire pareil sur mon df, mais je rencontre une erreur que je ne comprends pas..

Voici mon df

Code : Tout sélectionner

          ben_aaa_ano exe_soi_amd   pha_prs_c13 pha_prs_ide
79  UXBJ7000PUB0GHPDD  2015-01-06 3400935567260     3556726
390 DGAWXBU5TP4999MKD  2015-01-19 3400939681917     3968191
596 DGAWXBU5TP4999MKD  2015-01-19 3400949255689     4925568
772 DGAWXBU5TP4999MKD  2015-01-10 3400936583849     3658384
824 UXBJ7000PUB0GHPDD  2015-01-02 3400932905997     3290599
955 DGAWXBU5TP4JHHHHD  2015-01-19 3400936412026     3641202


lorsque je fais un

Code : Tout sélectionner

length(unique(df$ben_aaa_ano))

J'obtiens une réponse de 191, il y a donc 191 ben_aaa_ano différents;

Donc si j'éxécute cette fonction :

Code : Tout sélectionner

parano <- (split(df, df$ben_aaa_ano))


Il semblerait logique que j'obtienne un fichier avec 191 listes, or j'obtiens une 33005 listes...

Je ne comprends pas ce que je code mal..

Par avance, je vous remercie

Anais Payen
Messages : 60
Enregistré le : 25 Fév 2019, 08:50

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Anais Payen » 11 Avr 2019, 13:31

J'ai trouvé la réponse : mon df était une extraction d'un autre df, et tous les levels de cette colonne avait été conservés, il suffit de faire un droplevels poru le remettre à jour.

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

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Pierre-Yves Berrard » 11 Avr 2019, 13:34

Merci d'avoir pris le temps de partager la solution !
PY

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

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Mickael Canouil » 12 Avr 2019, 08:34

Bonjour,

Ceci est l'un des problèmes d'utiliser la conversion par défaut des chaînes de caractères en facteurs.
Je recommande de commencer vos scripts par:

Code : Tout sélectionner

options(stringsAsFactors = FALSE)


Ainsi, vous aurez à définir de façon explicites les facteurs, ce qui limitera considérablement les erreurs obscures du même style que celle que vous avez eu.

PS: Attention à l'utilisation de parenthèses sans raison, ce n'est pas "gratuit"

Code : Tout sélectionner

benchr::benchmark(
  (((1)+1)+1),
  1+1+1
)
#> Benchmark summary:
#> Time units : nanoseconds
#>             expr n.eval min lw.qu median mean up.qu  max total relative
#>  (((1) + 1) + 1)    100 278   297    314  377   382 2080 37700     1.65
#>        1 + 1 + 1    100 147   166    190  212   216  693 21200     1.00


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

Anais Payen
Messages : 60
Enregistré le : 25 Fév 2019, 08:50

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Anais Payen » 12 Avr 2019, 09:25

Mickael Canouil a écrit :Bonjour,

Ceci est l'un des problèmes d'utiliser la conversion par défaut des chaînes de caractères en facteurs.
Je recommande de commencer vos scripts par:

Code : Tout sélectionner

options(stringsAsFactors = FALSE)




Effectivement cela permet de supprimer les facteurs de base, sauf que pour split, j'ai besoin de facteurs, et je dois donc recoder mes 191 lignes.

La fonction droplevels permet de me donner tous les niveaux de mon facteur en supprimant ceux qui ont été exclus, j'espérais donc pouvoir faire un :

Code : Tout sélectionner

df$ben_aaa_ano <- as.factor (df$ben_aaa_ano, levels=c(droplevels(df$ben_aaa_ano)))


Mais il me note que l'argument est inutilisé.. Quelqu'un aurait une idée pour améliorer mon script?

Merci d'avance


PS : pas d'inquiétude pour la parenthèse à split, c'est une erreur lors de la recopie, mais merci pour la précision, je n'aurais pas pensé que cela avait une telle influence :)

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

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Mickael Canouil » 12 Avr 2019, 10:52

Anais Payen a écrit :Effectivement cela permet de supprimer les facteurs de base, sauf que pour split, j'ai besoin de facteurs, et je dois donc recoder mes 191 lignes.

Mais dans tous les cas, vous allez devoir recoder votre facteur pour n'inclure que les modalités présentes, comme c'est le cas ici dans votre essai.
Sauf, qu'au moins vous savez ce qui a été fait et comment.

Nul besoin d'utiliser droplevels() si vous voulez redéfinir votre variable.
De plus, ne pas confondre as.factor() qui est une fonction de conversion et factor() qui construit un variable factoriel.

La solution c'est soit:

Code : Tout sélectionner

df$ben_aaa_ano <- factor(df$ben_aaa_ano, levels = unique(df$ben_aaa_ano))
split(df, df$ben_aaa_ano)

(pas d'espace entre le nom de la fonction et la parenthèse ouvrante qui suit)

ou

Code : Tout sélectionner

split(df, droplevels(df$ben_aaa_ano))


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

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

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Pierre-Yves Berrard » 12 Avr 2019, 12:02

Anais Payen a écrit :sauf que pour split, j'ai besoin de facteurs

Même pas.
Ça marche avec des simples chaînes de caractères. Il faut juste que split puisse convertir en facteur (l'aide de la fonction est un peu trompeuse sur ce point).
PY

Anais Payen
Messages : 60
Enregistré le : 25 Fév 2019, 08:50

Re: Créer une liste de data frames à partir des individus d'un data frame

Messagepar Anais Payen » 12 Avr 2019, 13:11

Mickael Canouil a écrit :

Code : Tout sélectionner

df$ben_aaa_ano <- factor(df$ben_aaa_ano, levels = unique(df$ben_aaa_ano))
split(df, df$ben_aaa_ano)

(pas d'espace entre le nom de la fonction et la parenthèse ouvrante qui suit)

ou

Code : Tout sélectionner

split(df, droplevels(df$ben_aaa_ano))




Les 2 fonctionnent à merveille! Je ne comprends pas suffisament la doc de "droplevels" pour comprendre pourquoi la fonction "unique" fonctionne mais pas la droplevel dans votre 1ere proposition!

Merci pour votre réponse!



Pierre-Yves Berrard a écrit :
Anais Payen a écrit :sauf que pour split, j'ai besoin de facteurs

Même pas.
Ça marche avec des simples chaînes de caractères. Il faut juste que split puisse convertir en facteur (l'aide de la fonction est un peu trompeuse sur ce point).


Je ne dois pas bien utiliser la fonction alors, car lorsque j'avais des chaines de caractères, elle ne fonctionnait pas!
C'est vrai que l'aide parle bien de facteur!

Merci également :)


Retourner vers « Questions en cours »

Qui est en ligne

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

cron