Mam ramkę danych z 10 kolumnami, zbierającą akcje „użytkowników”, gdzie jedna z kolumn zawiera identyfikator (nie jest unikalny, identyfikujący użytkownika) (kolumna 10). długość ramki danych wynosi około 750000 wierszy. Próbuję wyodrębnić pojedyncze ramki danych (więc otrzymuję listę lub wektor ramek danych) podzielone według kolumny zawierającej identyfikator „użytkownika”, aby wyodrębnić działania pojedynczego aktora.
ID | Data1 | Data2 | ... | UserID
1 | aaa | bbb | ... | u_001
2 | aab | bb2 | ... | u_001
3 | aac | bb3 | ... | u_001
4 | aad | bb4 | ... | u_002
w wyniku
list(
ID | Data1 | Data2 | ... | UserID
1 | aaa | bbb | ... | u_001
2 | aab | bb2 | ... | u_001
3 | aac | bb3 | ... | u_001
,
4 | aad | bb4 | ... | u_002
...)
Poniższe działa bardzo dobrze dla mnie na małej próbce (1000 wierszy):
paths = by(smallsampleMat, smallsampleMat[,"userID"], function(x) x)
a następnie uzyskiwanie dostępu do elementu, który chcę, na przykład za pomocą ścieżek [1].
Podczas nakładania na oryginalną dużą ramkę danych lub nawet reprezentację macierzy, to dławi moją maszynę (4 GB RAM, MacOSX 10.6, R 2.15) i nigdy się nie kończy (wiem, że istnieje nowsza wersja R, ale uważam, że to nie jest główny problem ).
Wydaje się, że split jest bardziej wydajny i po długim czasie się kończy, ale nie wiem (gorsza znajomość R), jak podzielić wynikową listę wektorów na wektor macierzy.
path = split(smallsampleMat, smallsampleMat[,10])
Rozważałem również użycie big.matrix
itp., Ale bez większego sukcesu przyspieszyłoby to proces.
dlply(df, .(userid))
i stwierdziłem, że jest zła w porównaniu dosplit
nawet bez angażowania czasu wykonywaniarequire(plyr)
, dziękuję i OP!Od wersji 0.8.0
dplyr
oferuje przydatną funkcję o nazwiegroup_split()
:# On sample data from @Aus_10 df %>% group_split(g) [[1]] # A tibble: 25 x 3 ran_data1 ran_data2 g <dbl> <dbl> <fct> 1 2.04 0.627 A 2 0.530 -0.703 A 3 -0.475 0.541 A 4 1.20 -0.565 A 5 -0.380 -0.126 A 6 1.25 -1.69 A 7 -0.153 -1.02 A 8 1.52 -0.520 A 9 0.905 -0.976 A 10 0.517 -0.535 A # … with 15 more rows [[2]] # A tibble: 25 x 3 ran_data1 ran_data2 g <dbl> <dbl> <fct> 1 1.61 0.858 B 2 1.05 -1.25 B 3 -0.440 -0.506 B 4 -1.17 1.81 B 5 1.47 -1.60 B 6 -0.682 -0.726 B 7 -2.21 0.282 B 8 -0.499 0.591 B 9 0.711 -1.21 B 10 0.705 0.960 B # … with 15 more rows
Aby nie uwzględniać kolumny grupującej:
df %>% group_split(g, keep = FALSE)
źródło
Natknąłem się na tę odpowiedź i tak naprawdę chciałem OBIE grupy (dane zawierające tego jednego użytkownika i dane zawierające wszystko oprócz tego jednego użytkownika). Nie jest to konieczne ze względu na specyfikę tego posta, ale pomyślałem, że dodam na wypadek, gdyby ktoś szukał w Google tego samego problemu co ja.
df <- data.frame( ran_data1=rnorm(125), ran_data2=rnorm(125), g=rep(factor(LETTERS[1:5]), 25) ) test_x = split(df,df$g)[['A']] test_y = split(df,df$g!='A')[['TRUE']]
Oto jak to wygląda:
head(test_x) x y g 1 1.1362198 1.2969541 A 6 0.5510307 -0.2512449 A 11 0.0321679 0.2358821 A 16 0.4734277 -1.2889081 A 21 -1.2686151 0.2524744 A > head(test_y) x y g 2 -2.23477293 1.1514810 B 3 -0.46958938 -1.7434205 C 4 0.07365603 0.1111419 D 5 -1.08758355 0.4727281 E 7 0.28448637 -1.5124336 B 8 1.24117504 0.4928257 C
źródło