以更有效的方式将data.frame子集化为列表

时间:2013-05-14 16:44:13

标签: r

我有一个data.frame,其中2列代表2个基因之间的相互作用。如何查看data.frame:

的示例
head(df)
V1       V2
A1BG     A1BG
A1BG    CRISP3
A1CF     A1CF
A1CF   APOBEC1
A1CF    CUGBP2
A1CF     KHSRP

我想根据第一列的值拆分data.frame,我使用了以下命令:

out <- split(df, df$V1)

所需的输出应为:

out
$A1BG
[1] A1BG CRISP3

$A1CF
[2] A1CF APOBEC1 CUGBP2 KHSRP

然而,由于我的文件太大(大约200,000行),使用拆分的过程需要很长时间

非常感谢

1 个答案:

答案 0 :(得分:5)

为了加快速度,特别是如果您只需要df$V2分开df$V1,请在split的调用中仅使用该向量而不是整个数据框{{ 1}}。 E.g:

df

这是一个很少级别的例子。在很多级别上,分割整个数据帧的低效率开始在计算时间上严重影响,例如,对于一个大约10000级的因素:

## Dummy data
df <- read.table(text = "V1       V2
A1BG     A1BG
A1BG    CRISP3
A1CF     A1CF
A1CF   APOBEC1
A1CF    CUGBP2
A1CF     KHSRP", header = TRUE)
## make it big!
df <- with(df, cbind.data.frame(V1 = rep(V1, length.out = 1e5),
                                V2 = rep(V2, length.out = 1e5)))
# time it
system.time(sp1 <- split(df, df$V1))

system.time(sp2 <- split(df$V2, df$V1))

> system.time(sp1 <- split(df, df$V1))
   user  system elapsed 
  0.024   0.000   0.016 
> system.time(sp2 <- split(df$V2, df$V1))
   user  system elapsed 
  0.008   0.000   0.005

原因是在df2 <- data.frame(V1 = factor(sample(10000, 1e5, replace = TRUE)), V2 = rnorm(1e5)) system.time(sp3 <- split(df2, df2$V1)) system.time(sp4 <- split(df2$V2, df2$V1)) > system.time(sp3 <- split(df2, df2$V1)) user system elapsed 5.332 0.000 4.216 > > system.time(sp4 <- split(df2$V2, df2$V1)) user system elapsed 0.008 0.000 0.005 案例中,调用了split(df, df$V1)方法,它会对split.data.frame本身的lapply()分割成1:nrow(df)组{1}}(f),并将函数(df$V2)应用于每个组件。因此,随着级别数量的增加,对该匿名函数的函数调用次数会增加并使计算时间膨胀。

function(ind) x[ind, , drop = FALSE])情况下,使用split(df$V2, df$v1)方法,如果使用因子split.default调用,则基本上只需要调用f的快速C实现。因此,它不会产生调用匿名函数或重复调用split的任何开销。