df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
Jaki jest najprostszy sposób na rozwinięcie każdego wiersza do pierwszych dwóch kolumn ramki data.frame powyżej, tak aby każdy wiersz był powtarzany tyle razy, ile określono w kolumnie „freq”?
Innymi słowy, przejdź od tego:
df
var1 var2 freq
1 a d 1
2 b e 2
3 c f 3
Do tego:
df.expanded
var1 var2
1 a d
2 b e
3 b e
4 c f
5 c f
6 c f
data.frame
bardziej efektywna jest zastąpienierow.names(df)
zseq.int(1,nrow(df))
lubseq_len(nrow(df))
.stare pytanie, nowy czasownik w tidyverse:
źródło
Użyj
expandRows()
zsplitstackshape
opakowania:Prosta składnia, bardzo szybka, działa na
data.frame
lubdata.table
.Wynik:
źródło
Rozwiązanie @neilfws działa świetnie w przypadku
data.frame
s, ale nie w przypadkudata.table
s, ponieważ brakuje imrow.names
właściwości. To podejście działa w obu przypadkach:Kod
data.table
jest odrobinę czystszy:źródło
df[rep(seq(.N), freq)][, freq := NULL]
df[rep(1:.N, freq)][, freq:=NULL]
W przypadku, gdy musisz wykonać tę operację na bardzo dużych ramkach data.frames, polecam przekonwertowanie go na plik data.table i skorzystanie z następującego, które powinno działać znacznie szybciej:
Zobacz, o ile szybsze jest to rozwiązanie:
źródło
Error in rep(1, freq) : invalid 'times' argument
. Biorąc pod uwagę, że istnieje już odpowiedź data.table na to pytanie, możesz chcieć opisać, w jaki sposób Twoje podejście jest inne lub kiedy jest lepsze niż bieżąca odpowiedź data.table. Jeśli nie ma większej różnicy, możesz zamiast tego dodać go jako komentarz do istniejącej odpowiedzi.df
z pytania OP? Moja odpowiedź jest lepsza, ponieważ druga odpowiedź to rodzaj nadużyciadata.table
pakietu poprzez użyciedata.frame
składni, zobacz często zadawane pytaniadata.table
: „Generalnie złą praktyką jest odnoszenie się do kolumn według numeru, a nie nazwy”.df
opublikowanej przez OP, ale kiedy próbowałem porównać to z większym data.frame, otrzymałem ten błąd. Data.frame, której użyłem, brzmiała:set.seed(1) dfbig <- data.frame(var1=sample(letters, 1000, replace = TRUE), var2=sample(LETTERS, 1000, replace = TRUE), freq=sample(1:10, 1000, replace = TRUE))
W przypadku malutkiego data.frame podstawowa odpowiedź działa dobrze w moim benchmarkingu, po prostu nie skaluje się dobrze do większych data.frames. Pozostałe trzy odpowiedzi działały pomyślnie z tą większą ramką data.frame.data.table
składni, więc nie powinienem oceniać odpowiedzi.Inna
dplyr
alternatywaslice
polegająca na tym, że powtarzamy liczbęfreq
razy każdy wierszseq_len(n())
część można wymienić na dowolną z poniższych.źródło
Inną możliwością jest użycie
tidyr::expand
:Jednowierszowa wersja odpowiedzi vonjda :
Utworzono 21.05.2019 r. Przez pakiet reprex (v0.2.1)
źródło
Wiem, że tak nie jest, ale jeśli chcesz zachować oryginalną kolumnę freq, możesz użyć innego
tidyverse
podejścia wraz zrep
:Utworzony 21.12.2019 przez pakiet reprex (v0.3.0)
źródło
.remove = FALSE
wuncount()