1

2 つの遺伝子間の相互作用を表す 2 つの列を持つ data.frame があります。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行)、分割を使用したプロセスには非常に長い時間がかかります

どうもありがとう

4

1 に答える 1

5

これを高速化するには、特にdf$V2に基づいて分割するだけでよい場合は、データ フレーム全体ではなくdf$V1、呼び出しでそのベクトルのみを使用します。例えば:splitdf

## 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

ただし、これはいくつかのレベルの例です。非常に多くのレベルがあると、データ フレーム全体を分割する非効率性が計算時間に大きく影響し始めます。たとえば、約 10000 レベルの係数の場合です。

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)fdf$V2function(ind) x[ind, , drop = FALSE])

split(df$V2, df$v1)メソッドが使用される場合split.default、 factor で呼び出された場合、本質f的には の高速な C 実装を呼び出すだけで済みますsplit。そのため、無名関数を呼び出すオーバーヘッドも、 への繰り返し呼び出しも発生しません[

于 2013-05-14T17:15:02.407 に答える