web-dev-qa-db-fra.com

Réorganiser le dataframe dans une table, l'opposé de "fondre"

J'ai un énorme dataframe comme celui-ci:

SN = c(1:100, 1:100, 1:100, 1:100)  
class = c(rep("A1", 100), rep("B2", 100), rep("C3", 100), rep("D4", 100)) # total 6000 levels 
myvar = rnorm(400)
mydf = data.frame(SN, class, myvar) 

Je veux "fondre" dans une table avec chaque niveau comme colonne unique et myvar rempli:

SN          A1            B2          C3         D4       .............and so on for all 6000 

Comment puis-je y parvenir, je sais que c'est une question simple, mais je ne pouvais pas comprendre.

54
jon
> dcast(mydf, SN ~ class)

  SN         A1         B2          C3          D4
1  1  0.1461258  0.8325014  0.33562088 -0.07294576
2  2  0.5964182  0.4593710 -0.23652803 -1.52539568
3  3  2.0247742 -1.1235963  1.79875447 -1.87462227
4  4  0.8184004  1.3486721  0.76076486 -1.18311991
5  5 -0.6577212  0.3666741 -0.06057506  1.38825487
6  6  0.1590443  0.2043661  0.08161778  0.10421797
...
52
John Colby
molten = melt( mydf , id.vars = c( "SN" , "class" ) , measure.vars = "myvar" )
casted = dcast( molten , SN~class )
5
SFun28

Une autre approche avec split:

mydfSplit <- split(mydf[,-2], mydf$class, drop=TRUE)

Le résultat est une liste qui peut être facilement convertie en data.frame si les composants ont les mêmes dimensions (ce qui est vrai dans cet exemple):

mydf2 <- do.call(cbind, mydfSplit)

Le problème avec cette solution est que les noms du résultat final nécessitent un nettoyage. Cependant, pour des données plus générales, cela peut être utile si SN est différent pour chaque classe.

1
Oscar Perpiñán

En base R, vous pourriez le faire comme ça ...

# get it sorted so that all you need to do is make a matrix out of it
mydf <- mydf[order(mydf$class, mydf$SN),]
# save the unique values of SN
SNu <- unique(mydf$SN)
# combine a matrix with SN
mydfw <- data.frame(SNu, matrix(mydf$myvar, nrow = length(SNu)))
# name your columns    
colnames(mydfw) <- c('SN', levels(mydf$class))

Ou, pour une expression plus concise utilisant l'agrégat

aggregate(myvar~SN, mydf, 'c')
# column names don't come out great
colnames(mydfw) <- c('SN', levels(mydf$class))
1
John