2012-11-20 12 views
6

Załóżmy mam wektor a:R: Generowanie histogram od liczby danych

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

i wektor count b:

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

chciałbym wygenerować wektor c:

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

Aby zadzwonić:

hist(c) 

Jak mogę zbudować c, czy istnieje sposób na wygenerowanie histogramu bezpośrednio z a i b? Zwróć uwagę na duplikaty w a, a także na nierówne odstępy.

Wymagaj wektoryzowanego rozwiązania. a i b są zbyt duże dla lapo i przyjaciół.

Odpowiedz

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 ponieważ byłem ciekawy!

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

Cóż, będę przeklęty, nie spodziewałem się tego! – thelatemail

+0

Dobra * względna * przyspieszenie, ale niekoniecznie będzie czekać cały dzień w obie strony! – thelatemail

+0

To przyspieszenie nie nastąpiło w oczekiwanym kierunku! Ale rep zajmuje tylko 3 znaki do wpisania; Biorąc pod uwagę, że absolutny czas jest szybki w każdym przypadku, liczba postaci wygrywa dla mnie. Tak więc akceptowane rozwiązanie pozostaje. –

5

Właśnie na coś innego niż 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

zobacz edytuj mojego wpisu. twoja wersja 'inverse.rle' jest znacznie szybsza! – Justin

+0

@Justin, zobacz mój post - nie powinno być, a nie jest. – mnel

4

Some porównawczej i szybsze rozwiązanie. rep.int jest szybsza realizacja rep w standardowym przypadku użycia (od ?rep)

rep.int(a, b) 

nie był przekonany o benchmarkingu powyżej

inverse.rle jest tylko nakładką na rep.int. rep.int powinien być szybszy niż rep. Myślę, że składowa inverse.rlewrapper powinien być wolniejszy niż interpretacji rep() jako prymitywne funkcji

Niektóre 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 

Nie ma zbyt wiele w niej, ale rep.int pojawia się zwycięzcy - co to powinien.

+2

+1 - Cóż, nie będę potępiony, jak się wydaje. – thelatemail

+0

rep.int dla "wewnętrznego"; nie "integer"; o konwencje nazewnictwa R ... Bardzo dziękuję za wpis za pomocą narzędzia microbenchmark; Tego wieczoru nauczyłem się kilku rzeczy. –