Как разделить фрейм данных?

Я хочу разделить фрейм данных на несколько более мелких. Это выглядит очень тривиальным вопросом, однако я не могу найти решение в веб-поиске.


person Leo5188    schedule 21.07.2010    source источник
comment
никогда не понимал split(), но с помощью ntile from dplyr и последующей фильтрации по групповому индексу (квартилю) сделал то, что хотел: group = df[df$quartile==i,].   -  person jozxyqk    schedule 17.02.2015


Ответы (8)


Вы также можете разрезать фрейм данных на произвольное количество меньших фреймов данных. Здесь мы разрезаем два фрейма данных.

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

дает

$`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

Вы также можете разделить фрейм данных на основе существующего столбца. Например, чтобы создать три фрейма данных на основе столбца cyl в mtcars:

split(mtcars,mtcars$cyl)
person Greg    schedule 21.07.2010
comment
Привет, Грег, я не мог понять синтаксис примера команды, можешь объяснить. - person Anirudh; 01.02.2015
comment
Вы также можете разрезать фрейм данных на произвольное количество меньших фреймов данных. Здесь мы разрезаем два фрейма данных. Как это произвольное количество кадров данных, если вы указываете здесь два кадра данных? - person user5359531; 16.03.2016
comment
@user5359531 user5359531, здесь два произвольных фрейма данных. - person Demo; 11.12.2016

Если вы хотите разделить кадр данных в соответствии со значениями какой-либо переменной, я бы предложил использовать daply() из пакета plyr.

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

Теперь x — это массив фреймов данных. Чтобы получить доступ к одному из фреймов данных, вы можете проиндексировать его именем уровня переменной разделения.

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

Я был бы уверен, что нет других более умных способов работы с вашими данными, прежде чем разбивать их на множество фреймов данных.

person JoFrhwld    schedule 21.07.2010
comment
пожалуйста, укажите заранее пакет, из которого небазовая функция - предположительно, вы имеете в виду daply из пакета plyr? - person mdsumner; 22.07.2010
comment
Я загрузил plyr в свой фрагмент кода, поэтому подумал, что это понятно, но я отредактирую прозу ответа для ясности. - person JoFrhwld; 22.07.2010
comment
Сначала я предложил dlply, но он не называл записи автоматически по группирующей переменной. Я не знаю, что я сделал сначала, но, по-видимому, daply не работает, если не указана функция. Я отредактировал ответ на работу. - person JoFrhwld; 22.07.2010

Я только что опубликовал своего рода RFC, который может вам помочь: Разделить вектор на куски в 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

Привет, Себастьян

person Sebastian    schedule 23.07.2010

Вы также можете использовать

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

Это создаст фрейм данных со значениями, где sum_points = 2500

Это дает :

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
person Dimitar Slavchev    schedule 28.07.2011
comment
привет, как бы вы поступили, если бы захотели динамически разделить его на другой data_frame на основе уникальных значений в этом столбце? - person kRazzy R; 06.04.2017

subset() также полезен:

subset(DATAFRAME, COLUMNNAME == "")

Для пакета опроса, возможно, подходит пакет survey?

http://faculty.washington.edu/tlumley/survey/

person apeescape    schedule 21.07.2010

Ответ, который вы хотите, во многом зависит от того, как и почему вы хотите разбить фрейм данных.

Например, если вы хотите исключить некоторые переменные, вы можете создать новые фреймы данных из определенных столбцов базы данных. Нижние индексы в скобках после фрейма данных относятся к номерам строк и столбцов. Проверьте Spoetry для полного описания.

newdf <- mydf[,1:3]

Или вы можете выбрать определенные строки.

newdf <- mydf[1:3,]

И эти индексы также могут быть логическими тестами, такими как выбор строк, содержащих определенное значение, или факторов с желаемым значением.

Что вы хотите сделать с оставшимися кусками? Вам нужно выполнить одну и ту же операцию для каждого фрагмента базы данных? Затем вам нужно убедиться, что подмножества фрейма данных заканчиваются в удобном объекте, таком как список, который поможет вам выполнить одну и ту же команду для каждого фрагмента фрейма данных.

person Ben M    schedule 22.07.2010

Если вы хотите разделить значения в одном из столбцов, вы можете использовать lapply. Например, чтобы разделить ChickWeight на отдельный набор данных для каждого цыпленка:

data(ChickWeight)
lapply(unique(ChickWeight$Chick), function(x) ChickWeight[ChickWeight$Chick == x,])
person mikeck    schedule 20.01.2015

Разделение фрейма данных кажется контрпродуктивным. Вместо этого используйте парадигму разделения-применения-объединения, например, сгенерируйте некоторые данные

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

затем разделите только соответствующие столбцы и примените функцию scale() к x в каждой группе и объедините результаты (используя split<- или 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)

Это будет очень быстро по сравнению с разделением data.frames, и результат останется пригодным для последующего анализа без повторения. Я думаю, что синтаксис dplyr

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

В целом, это решение dplyr работает быстрее, чем разделение кадров данных, но не так быстро, как разделение-применение-объединение.

person Martin Morgan    schedule 19.07.2016