2010-07-21 23 views
59

Chcę podzielić ramkę danych na kilka mniejszych. Wygląda to na bardzo banalne pytanie, ale nie mogę znaleźć rozwiązania z wyszukiwarki internetowej.Jak podzielić ramkę danych?

+1

Nigdy nie rozumiałem 'split()', ale używając ['ntile' z' dplyr'] (http://stackoverflow.com/a/27646599/1888983), a następnie filtrowanie według indeksu grupy ("kwartylu"), co chciałem: 'group = df [df $ quartile == i,]'. – jozxyqk

Odpowiedz

18

Jeśli chcesz podzielić ramkę danych według wartości jakiejś zmiennej, sugeruję użycie daply() z pakietu plyr.

library(plyr) 
x <- daply(df, .(splitting_variable), function(x)return(x)) 

Teraz x to tablica ramek danych. Aby uzyskać dostęp do jednej z ramek danych, można zaindeksować ją nazwą poziomu zmiennej dzielącej.

x$Level1 
#or 
x[["Level1"]] 

byłbym pewien, że nie istnieją inne, bardziej sprytne sposoby radzenia sobie z danymi przed dzieląc go na wielu dataframes chociaż.

+0

proszę podać z góry paczkę, z której pochodzi funkcja inna niż podstawowa - prawdopodobnie masz na myśli daply z pakietu plyr? – mdsumner

+0

Załadowałam plyr w moim fragmencie kodu, więc pomyślałem, że to było jasne, ale będę edytować wersję prozy dla jasności. – JoFrhwld

+1

Czy nie masz na myśli 'dl''? – hadley

51

Można też wyciąć ramkę danych do dowolnej liczby mniejszych dataframes. Tutaj podzieliliśmy na dwie ramki danych.

x = data.frame(num = 1:26, let = letters, LET = LETTERS) 
set.seed(10) 
split(x, sample(rep(1:2, 13))) 

daje

$`1` 
    num let LET 
3 3 c C 
6 6 f F 
10 10 j J 
12 12 l L 
14 14 n N 
15 15 o O 
17 17 q Q 
18 18 r R 
20 20 t T 
21 21 u U 
22 22 v V 
23 23 w W 
26 26 z Z 

$`2` 
    num let LET 
1 1 a A 
2 2 b B 
4 4 d D 
5 5 e E 
7 7 g G 
8 8 h H 
9 9 i I 
11 11 k K 
13 13 m M 
16 16 p P 
19 19 s S 
24 24 x X 
25 25 y Y 
+0

Greg, Twoje rozwiązanie działa! dzięki. – Leo5188

+0

Bez problemu. Cieszę się, że tak. – Greg

+1

Hej greg, nie mogłem zrozumieć składni przykładowego polecenia, możesz to wyjaśnić. – Anirudh

3

Odpowiedź chcesz zależy w dużej mierze od tego, jak i dlaczego chcesz zerwać z ramki danych.

Na przykład, jeśli chcesz pominąć niektóre zmienne, możesz utworzyć nowe ramki danych z określonych kolumn bazy danych. Indeksy dolne w nawiasach po ramce danych odnoszą się do numerów wierszy i kolumn. Sprawdź Spoeze dla pełnego opisu.

newdf <- mydf[,1:3] 

Lub możesz wybrać określone wiersze.

newdf <- mydf[1:3,] 

I te indeksy dolne mogą być również testami logicznymi, takimi jak wybieranie wierszy zawierających określoną wartość lub czynniki o pożądanej wartości.

Co chcesz zrobić z pozostałymi porcjami? Czy musisz wykonać tę samą operację na każdym fragmencie bazy danych? Wtedy będziesz chciał upewnić się, że podzbiory ramki danych znajdą się w wygodnym obiekcie, takim jak lista, która pomoże ci wykonać to samo polecenie na każdym fragmencie ramki danych.

12

Właśnie napisali rodzaju RFC, które mogą pomóc: Split a vector into chunks in R

x = data.frame(num = 1:26, let = letters, LET = LETTERS) 
## number of chunks 
n <- 2 
dfchunk <- split(x, factor(sort(rank(row.names(x))%%n))) 
dfchunk 
$`0` 
    num let LET 
1 1 a A 
2 2 b B 
3 3 c C 
4 4 d D 
5 5 e E 
6 6 f F 
7 7 g G 
8 8 h H 
9 9 i I 
10 10 j J 
11 11 k K 
12 12 l L 
13 13 m M 

$`1` 
    num let LET 
14 14 n N 
15 15 o O 
16 16 p P 
17 17 q Q 
18 18 r R 
19 19 s S 
20 20 t T 
21 21 u U 
22 22 v V 
23 23 w W 
24 24 x X 
25 25 y Y 
26 26 z Z 

Wiwaty, Sebastian

10

Można też użyć

data2 <- data[data$sum_points == 2500, ] 

Będzie to dataframe z wartości, w których suma punktów = 2500

Daje:

airfoils sum_points field_points init_t contour_t field_t 
... 
491  5  2500   5625 0.000086 0.004272 6.321774 
498  5  2500   5625 0.000087 0.004507 6.325083 
504  5  2500   5625 0.000088 0.004370 6.336034 
603  5  250  10000 0.000072 0.000525 1.111278 
577  5  250  10000 0.000104 0.000559 1.111431 
587  5  250  10000 0.000072 0.000528 1.111524 
606  5  250  10000 0.000079 0.000538 1.111685 
.... 
> data2 <- data[data$sum_points == 2500, ] 
> data2 
airfoils sum_points field_points init_t contour_t field_t 
108  5  2500   625 0.000082 0.004329 0.733109 
106  5  2500   625 0.000102 0.004564 0.733243 
117  5  2500   625 0.000087 0.004321 0.733274 
112  5  2500   625 0.000081 0.004428 0.733587 
+0

cześć, jak byś poszła, gdybyś chciał podzielić go dynamicznie na inną ramkę danych na podstawie unikalnych wartości w tej kolumnie.? –

3

Jeśli chcesz podzielić przez wartość w jednej z kolumn, można użyć lapply. Na przykład, aby podzielić ChickWeight w osobnym zbiorze danych dla każdego pisklęcia:

data(ChickWeight) 
lapply(unique(ChickWeight$Chick), function(x) ChickWeight[ChickWeight$Chick == x,]) 
1

Dzielenie ramka danych wydaje się nieproduktywne. Zamiast tego należy użyć split-apply-łączą paradygmatu, na przykład wygenerować pewne dane

df = data.frame(grp=sample(letters, 100, TRUE), x=rnorm(100)) 

następnie rozdzielone jedynie odpowiednie kolumny i zastosować funkcję scale() do X w każdej grupie i połączyć wyniki (używając split<- lub ave)

df$z = 0 
split(df$z, df$grp) = lapply(split(df$x, df$grp), scale) 
## alternative: df$z = ave(df$x, df$grp, FUN=scale) 

To będzie bardzo szybkie w porównaniu do podziału danych.frames, a wynik pozostanie użyteczny w dalszej analizie bez iteracji. Myślę, że składnia dplyr jest

library(dplyr) 
df %>% group_by(grp) %>% mutate(z=scale(x)) 

W ogóle to rozwiązanie dplyr jest szybsze niż dzielenie ramek danych, ale nie tak szybko, jak split-zastosowanie-kombajnu.

Powiązane problemy