如何分割数据框?

86

我想将一个数据框分成几个较小的数据框。这似乎是一个非常琐碎的问题,但是我在网络搜索中找不到解决方案。


3
我从未理解split()函数,但是通过使用dplyr中的ntile()函数来将数据划分为等分位数,并根据组索引(“四分位数”)筛选所需数据,达到了我想要的效果:group = df[df$quartile==i,] - jozxyqk
8个回答

71

您可能还希望将数据框切割成任意数量的较小数据框。在这里,我们将其分为两个数据框。

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

您还可以根据现有列来拆分数据框。例如,要基于mtcars中的cyl列创建三个数据框:

split(mtcars,mtcars$cyl)

1
嘿,格雷格,我不理解示例命令的语法,请你能否解释一下。 - Anirudh
您可能还想将数据框切割成任意数量的小数据框。在这里,我们将其分为两个数据框。如果您在此处指定了两个数据框,那么它如何成为任意数量的数据框呢? - user5359531
2
@user5359531,这里有任意两个数据框。 - Demo

19
如果您想要根据某个变量的值来拆分一个数据框,我建议使用plyr包中的daply()函数。
library(plyr)
x <- daply(df, .(splitting_variable), function(x)return(x))

现在,x 是一个包含多个数据框的数组。要访问其中一个数据框,您可以使用分割变量级别的名称对其进行索引。

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

在将数据拆分成多个数据帧之前,我会确保没有其他更聪明的方法来处理您的数据。


请明确说明非基本函数所属的包 - 您可能是指plyr包中的daply函数? - mdsumner
我在我的代码片段中加载了plyr,所以我认为很清楚,但我会编辑答案的散文以使其更清晰。 - JoFrhwld
我首先建议使用dlply,但是它没有根据分组变量自动命名条目。我不记得我最初是怎么做的,但显然除非指定一个函数,否则daply无法工作。我编辑了答案使其能够工作。 - JoFrhwld

16

你也可以使用

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

你好,如果你想根据该列中的唯一值动态地将其拆分到不同的数据框中,你会怎么做呢? - kRazzy R

13

我刚刚发布了一份可能会对你有帮助的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

您好,Sebastian


8
你想要的答案在很大程度上取决于你想如何以及为什么要分割数据框。例如,如果你想省略一些变量,可以从数据库的特定列创建新的数据框。方括号中的下标代表行和列的编号。请参考Spoetry获取完整的描述。
newdf <- mydf[,1:3]

或者,您可以选择特定的行。
newdf <- mydf[1:3,]

这些下标也可以是逻辑测试,比如选择包含特定值的行或具有所需值的因子。

你想对剩余的块做什么?需要在数据库的每个块上执行相同的操作吗?那么你需要确保数据框的子集最终以方便的对象(例如列表)形式出现,这将帮助你在数据框的每个块上执行相同的命令。


7

3

如果你想按照某一列的值进行拆分,可以使用lapply函数。例如,要将ChickWeight按每只小鸡拆分为单独的数据集:

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

3

将数据框拆分似乎是适得其反的。相反,使用拆分-应用-组合范式,例如,生成一些数据。

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

然后仅拆分相关列,并在每个组中对 x 应用 scale() 函数,最后将结果合并 (使用 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)

与拆分数据框相比,这将会非常快速,并且结果在下游分析中仍然可用而无需迭代。我认为dplyr的语法是

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

通常情况下,这个dplyr解决方案比分离数据框快,但不如分离应用合并(split-apply-combine)快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接