Как разделить фрейм данных? - PullRequest
66 голосов
/ 21 июля 2010

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

Ответы [ 8 ]

56 голосов
/ 21 июля 2010

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

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)
19 голосов
/ 21 июля 2010

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

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

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

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

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

12 голосов
/ 28 июля 2011

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

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
11 голосов
/ 23 июля 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

Cheers, Себастьян

7 голосов
/ 21 июля 2010

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

subset(DATAFRAME, COLUMNNAME == "")

Для пакета опросов может быть уместен пакет survey?

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

4 голосов
/ 22 июля 2010

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

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

newdf <- mydf[,1:3]

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

newdf <- mydf[1:3,]

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

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

3 голосов
/ 19 июля 2016

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

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 быстрее, чем разбиение фреймов данных, но не так быстро, как split-apply-Объединить.

3 голосов
/ 20 января 2015

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

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