如何分割数据帧?


74

我想将一个数据帧分成几个较小的帧。这看起来是一个非常琐碎的问题,但是我无法从网络搜索中找到解决方案。


3
永远无法理解split(),但使用ntile来自dplyr然后由组索引(“四分”)过滤做了我想要的东西:group = df[df$quartile==i,]
jozxyqk 2015年

Answers:


62

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

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)

1
嗨,格雷格,我不明白示例命令的语法,您能解释一下吗。
Anirudh 2015年

“您可能还希望将数据帧切成任意数量的较小数据帧。在这里,我们将切成两个数据帧。” 如果您在此处指定两个数据帧,这如何是任意数量的数据帧?
user5359531 2016年

2
@ user5359531,这里任意两个数据帧。
演示

19

如果要根据某个变量的值拆分数据帧,建议daply()plyr包中使用。

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

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

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

我可以肯定,在将数据分割成许多数据帧之前,没有其他更聪明的方法来处理您的数据。


请预先声明非基本函数来自的软件包-大概是从plyr软件包中获取?
mdsumner

我在代码片段中加载了plyr,所以我认为这很清楚,但是为了清楚起见,我将编辑答案文章。
JoFrhwld

dlply首先提出了建议,但是它并没有通过分组变量自动命名条目。我不知道我首先做了什么,但是daply除非指定了函数,否则显然是行不通的。我编辑了工作答案。
2010年

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

欢呼声,塞巴斯蒂安


13

您也可以使用

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

嗨,如果要基于该列中的唯一值将其动态拆分为另一个data_frame,该怎么办?
kRazzy R


6

您想要的答案在很大程度上取决于您如何以及为什么要破坏数据帧。

例如,如果要省略一些变量,则可以从数据库的特定列创建新的数据框。数据框后方括号中的下标指的是行号和列号。查看Spoetry以获取完整的描述。

newdf <- mydf[,1:3]

或者,您可以选择特定的行。

newdf <- mydf[1:3,]

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

您想对剩下的块做什么?您是否需要对数据库的每个块执行相同的操作?然后,您将要确保数据框的子集以方便的对象(例如列表)结尾,这将有助于您在数据框的每个块上执行相同的命令。


3

如果要按其中一列的值进行拆分,可以使用lapply。例如,将ChickWeight每个小鸡拆分成单独的数据集:

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

3

拆分数据帧似乎适得其反。而是使用split-apply-combine范例,例如,生成一些数据

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-combine快。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.