313 votes

Comment remodeler les données du format long au format large

J'ai des difficultés à réorganiser le cadre de données suivant :

set.seed(45)
dat1 <- data.frame(
    name = rep(c("firstName", "secondName"), each=4),
    numbers = rep(1:4, 2),
    value = rnorm(8)
    )

dat1
       name  numbers      value
1  firstName       1  0.3407997
2  firstName       2 -0.7033403
3  firstName       3 -0.3795377
4  firstName       4 -0.7460474
5 secondName       1 -0.8981073
6 secondName       2 -0.3347941
7 secondName       3 -0.5013782
8 secondName       4 -0.1745357

Je veux le remodeler de façon à ce que chaque variable unique "nom" soit un rowname, avec les "valeurs" comme observations sur cette ligne et les "nombres" comme colnames. Un peu comme ceci :

     name          1          2          3         4
1  firstName  0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357

J'ai regardé melt et cast et quelques autres choses, mais rien ne semble faire l'affaire.

3 votes

6 votes

@Frank : c'est un bien meilleur titre. formulaire long et grand format sont les termes standards utilisés. L'autre réponse ne peut être trouvée en effectuant une recherche sur ces termes.

308voto

Chase Points 27342

Utilisation de reshape fonction :

reshape(dat1, idvar = "name", timevar = "numbers", direction = "wide")

14 votes

+1 et vous n'avez pas besoin de vous appuyer sur des paquets externes, car reshape est livré avec stats . Sans compter que c'est plus rapide ! =)

0 votes

@indra_patil - J'utiliserais probablement le paquet reshape2 comme indiqué dans l'une des autres réponses. Vous pourriez créer une nouvelle question spécifique à votre cas d'utilisation et la poster si vous ne trouvez pas la solution.

0 votes

Il semble que cela va créer des colonnes "nom" dupliquées, ce qui peut être voulu ou non par l'auteur de ce fil de discussion.

147voto

Gregor Points 6270

Le nouveau (en 2014) tidyr fait également cela simplement, avec gather() / spread() étant les termes pour melt / cast .

Edit : Aujourd'hui, en 2019, tidyr v 1.0 a été lancé et a mis en place spread et gather sur un chemin de dépréciation, préférant plutôt pivot_wider et pivot_longer que vous pouvez trouver décrit dans cette réponse . Lisez la suite si vous voulez avoir un bref aperçu de la brève vie de spread/gather .

library(tidyr)
spread(dat1, key = numbers, value = value)

De github ,

tidyr est un recadrage de reshape2 conçu pour accompagner le cadre de données ordonnées, et pour travailler main dans la main avec magrittr et dplyr pour construire un pipeline solide pour l'analyse des données.

Tout comme reshape2 a fait moins que de remodeler, tidyr fait moins que reshape2 . Il est conçu spécifiquement pour le rangement des données, et non pas pour le remodelage général que l'on peut faire avec les données. reshape2 fait, ou l'agrégation générale que reshape a fait. En particulier, les méthodes intégrées ne fonctionnent que pour les cadres de données, et tidyr ne fournit aucune marge ni agrégation.

6 votes

Je voulais juste ajouter un lien vers le Livre de cuisine R qui traite de l'utilisation de ces fonctions à partir de tidyr et reshape2 . Il fournit de bons exemples et de bonnes explications.

80voto

Ista Points 3100

Vous pouvez le faire avec le reshape() ou avec la fonction melt() / cast() dans le paquet reshape. Pour la deuxième option, le code d'exemple est

library(reshape)
cast(dat1, name ~ numbers)

Ou en utilisant reshape2

library(reshape2)
dcast(dat1, name ~ numbers)

3 votes

Il est intéressant de noter que la simple utilisation de cast ou dcast ne fonctionnera pas bien si vous n'avez pas une colonne "valeur" claire. Essayez dat <- data.frame(id=c(1,1,2,2),blah=c(8,4,7,6),index=c(1,2,1,2)); dcast(dat, id ~ index); cast(dat, id ~ index) et vous n'obtiendrez pas ce que vous attendez. Vous devez noter explicitement les value/value.var - cast(dat, id ~ index, value="blah") et dcast(dat, id ~ index, value.var="blah") par exemple.

0 votes

Notez que reshape2 est déprécié et que vous devriez migrer votre code sans l'utiliser.

3 votes

@dpel Une tournure plus optimiste serait de dire que reshape2 est enfin terminé et que vous pouvez maintenant l'utiliser sans craindre que Hadley le change à nouveau et casse votre code !

52voto

SymbolixAU Points 15470

Une autre option si la performance est un souci est d'utiliser data.table L'extension par l'UE de reshape2 fonctions melt & dcast de l'entreprise

( Référence : Remaniement efficace à l'aide de data.tables )

library(data.table)

setDT(dat1)
dcast(dat1, name ~ numbers, value.var = "value")

#          name          1          2         3         4
# 1:  firstName  0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684  0.4874291 0.7383247 0.5757814

Et, à partir de data.table v1.9.6, nous pouvons effectuer des castings sur plusieurs colonnes.

## add an extra column
dat1[, value2 := value * 2]

## cast multiple value columns
dcast(dat1, name ~ numbers, value.var = c("value", "value2"))

#          name    value_1    value_2   value_3   value_4   value2_1   value2_2 value2_3  value2_4
# 1:  firstName  0.1836433 -0.8356286 1.5952808 0.3295078  0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684  0.4874291 0.7383247 0.5757814 -1.6409368  0.9748581 1.476649 1.1515627

8 votes

data.table l'approche est la meilleure ! très efficace ... vous verrez la différence quand name est une combinaison de 30-40 colonnes ! !!

0 votes

Et si je voulais prendre le maximum ?

0 votes

@T.Fung Je ne comprends pas ce que vous demandez. Il serait peut-être préférable d'ouvrir une nouvelle question ?

28voto

Jim M. Points 1883

En utilisant votre exemple de dataframe, nous pourrions :

xtabs(value ~ name + numbers, data = dat1)

2 votes

Celui-ci est bon, mais le résultat est un tableau de format qui n'est peut-être pas aussi facile à manipuler que data.frame ou data.table, qui ont tous deux de nombreux paquets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X