2013-07-30 13 views
6

Esiste un modo in R per convertire colonne in righe mantenendo il nome della colonna?Converti colonne in righe mantenendo il nome della colonna

ingresso Esempio:

A B 
1 1 
2 3 
3 4 
44 5 

uscita

Group Number 
    A  1 
    A  2 
    A  3 
    A  44 
    B  1 
    B  3 
    B  4 
    B  5 
+1

termini di ricerca Che cosa avete provato prima di chiedere qui? – Roland

+0

Le parole buzz per la ricerca sono "melt", "cast", "reshape", "wide" e "long". –

risposta

9

uso reshape2.

> x <- data.frame(A = 1:5, B = 55:51) 
> library(reshape2) 
> melt(x) 
Using as id variables 
    variable value 
1   A  1 
2   A  2 
3   A  3 
4   A  4 
5   A  5 
6   B 55 
7   B 54 
8   B 53 
9   B 52 
10  B 51 

E 'stato interessante vedere i parametri. melt stampa un messaggio per impostazione predefinita che possiamo disattivare essendo più esplicito quando si chiama una funzione.

> microbenchmark(stack(DF), melt(DF), times=100) 
    Unit: milliseconds 
      expr  min  lq median  uq  max neval 
    stack(DF) 122.3086 133.8435 139.6990 180.5338 250.9316 100 
     melt(DF) 140.0183 198.2025 227.8125 245.3444 367.1552 100 

trovo la differenza piccola, e diventa più piccolo quando la stampa per melt è spento. Sembra che la mia impressione di girare in modalità verbosa nelle mie simulazioni possa aver aiutato.

> microbenchmark(stack(DF), melt(DF, measure.vars = names(DF)[grepl("X", names(DF))]), times=100) 
Unit: milliseconds 
                 expr  min  lq median  uq  max neval 
               stack(DF) 94.33681 124.9958 132.1747 144.7323 287.7438 100 
melt(DF, measure.vars = names(DF)[grepl("X", names(DF))]) 99.44282 141.0594 150.2625 178.8081 249.0888 100 
10

Non c'è bisogno di usare reshape2, è possibile utilizzare la funzione di stack dalla base-R:

Con your.data come vostro esempio:

res <- stack(your.data) 
colnames(res) = c("Number", "Group") 

ti dà

> res 
    Number Group 
1  1  A 
2  2  A 
3  3  A 
4  44  A 
5  1  B 
6  3  B 
7  4  B 
8  5  B 

Vedi anche here.


Benchmarking melt da reshape2 e stack dalla base di dati più grande:

require(reshape2) 
set.seed(45) 
DF <- data.frame(matrix(sample(20, 1e6, TRUE), ncol=100)) 

require(microbenchmark) 
microbenchmark(stack(DF), melt(DF), times=100) 

Unit: milliseconds 
     expr  min  lq median  uq  max neval 
stack(DF) 157.7084 187.1993 241.8206 251.7132 334.5488 100 
    melt(DF) 174.6079 253.1088 261.6234 273.3971 443.9953 100 

Sembra come stack è più veloce, ma con un margine di 20 millisecondi ...

+0

@Thomas, sarebbe utile anche modificare il benchmarking nel post (preferibilmente con dati più grandi). – Arun

+0

@Thomas, non sembra il doppio più veloce ... almeno con questa dimensione dei dati. – Arun

+0

Se intendi facendo "system.time", allora sì, è molto probabile che sia incoerente. – Arun

Problemi correlati