2012-11-20 20 views
6

Supponiamo che io abbia vettore a:R: Generare istogramma dai conti di dati

c(1, 6, 2, 4.1, 1, 2) 

E un vettore conteggio b:

c(2,3,2,1,1,0) 

mi piacerebbe per generare vettore c:

c(1, 1, 6, 6, 6, 2, 2, 4.1, 1) 

Per chiamare:

hist(c) 

Come posso costruire c, o c'è un modo per generare l'istogramma direttamente da a e b? Notare i duplicati in a e la spaziatura non uguale.

Richiedi una soluzione vettoriale. a e b sono troppo grandi per lapply e gli amici.

risposta

10

?rep

> rep(a, b) 
[1] 1.0 1.0 6.0 6.0 6.0 2.0 2.0 4.1 1.0 
> 

Edit da quando ero curioso!

a <- sample(1:10, 1e6, replace=TRUE) 
b <- sample(1:10, 1e6, replace=TRUE) 

> system.time(rep(a, b)) 
    user system elapsed 
    0.140 0.016 0.156 
> system.time(inverse.rle(list(lengths=b, values=a))) 
    user system elapsed 
    0.024 0.004 0.028 
+0

Beh, sarò dannato, non me lo aspettavo! – thelatemail

+0

Un buon * relativo * si accelera, ma non esattamente starà aspettando tutto il giorno in entrambi i casi! – thelatemail

+0

Quell'accelerazione non è avvenuta nella direzione che mi aspettavo! Ma la ripetizione richiede solo 3 caratteri per digitare; Dato che il tempo assoluto è veloce in entrambi i casi, il numero di personaggi vince per me. Quindi la soluzione accettata rimane. –

5

solo per qualcosa di diverso rispetto rep:

> inverse.rle(list(lengths=b,values=a)) 
[1] 1.0 1.0 6.0 6.0 6.0 2.0 2.0 4.1 1.0 
+0

vedi la modifica al mio post. la tua versione 'inverse.rle' è molto più veloce! – Justin

+0

@Justin, guarda il mio post: non dovrebbe essere e non lo è. – mnel

4

Alcuni benchmarking e una soluzione più veloce. rep.int è una più rapida attuazione del rep nel caso d'uso standard (da ?rep)

rep.int(a, b) 

non mi ha convinto su un'analisi comparativa sopra

inverse.rle è solo un wrapper per rep.int. rep.int dovrebbe essere più veloce di rep. Vorrei pensare che la componente wrapper di inverse.rle dovrebbe essere più lento rispetto l'interpretazione di rep() in funzione primitiva

Alcuni microbenchmarking

library(microbenchmark) 

microbenchmark(rep(a,b), rep.int(a,b), 
     inverse.rle(list(values = a, lengths =b))) 
Unit: milliseconds 
             expr  min  lq median  uq 
1 inverse.rle(list(values = a, lengths = b)) 29.06968 29.26267 29.36191 29.67501 
2         rep(a, b) 25.65125 25.76246 25.84869 26.52348 
3        rep.int(a, b) 20.38604 23.31840 23.38940 23.69600 
     max 
1 72.80645 
2 69.00169 
3 66.40759 

Non c'è molto in essa, ma rep.int appare il vincitore - cui dovrebbero.

+2

+1 - Beh, non sarò dannato, sembra. – thelatemail

+0

rep.int per 'interno'; non "intero"; oh le convenzioni di denominazione R ... Grazie mille per il post che utilizza lo strumento microbenchmark; Ho imparato alcune cose questa sera di sicuro. –

Problemi correlati