1

行を追加する 2 列と 40 行の data.frame を初期化しようとしています。これは私が持っているコードです -

result.frame = as.data.frame(matrix(ncol=2, nrow=10))
names(result.frame) = c("ID", "Value")
for (i in 1:10) {
    value = somefunction(i)
    rbind(result.frame, c(i, value))
}

これを実行すると、NA を含む data.frame が取得されます。また、動的に成長する構造体は R でコーディングする最も効率の悪い方法の 1 つであることを SO で読みました。これが正しい場合、このようなことを達成する正しい方法は何ですか?

どうもありがとう!

4

2 に答える 2

6

結果フレームを何にも割り当てていません! 以下のコードは、あなたが示そうとしていると私が思うことを実行します。ただし、おっしゃる通り非効率です。

result.frame = as.data.frame(matrix(ncol=2, nrow=10))
names(result.frame) = c("ID", "Value")
for (i in 1:10) {
    value = 2 * i
    result.frame = rbind(result.frame, c(i, value))
}

代わりに、data.frame を必要なフル サイズにして、それに割り当てます。

result.frame = as.data.frame(matrix(ncol=2, nrow=20))
names(result.frame) = c("ID", "Value")
for (i in 11:20) {
    value = 2 * i
    result.frame[i,] = c(i, value)
}

簡単なタイミング:

> result.frame=data.frame()
> system.time(for(i in 1:10000){result.frame=rbind(result.frame, c(i,i*2))})
   user  system elapsed 
  9.844   0.000   9.874 

> result.frame=as.data.frame(matrix(ncol=2, nrow=10000))
> system.time(for(i in 1:10000){result.frame[i,]=c(i,i*2)})
   user  system elapsed 
  7.041   0.056   7.120 
> 

時間効率のほかに、データが大きくなるにつれて重要なメモリの問題もあります。操作を実行するrbindには、データをコピーする必要があります。つまり、連続したブロックで 2 倍のメモリが必要になります。既に作成されたものへの割り当てには、data.frameこの問題はありません。

于 2012-10-11T14:43:14.273 に答える
3

何が起こるかは次のとおりmatrixです。値で初期化していないため、NA は から来ています。rbind戻り値を破棄したため、何もしません。

result.frame = data.frame( ) 
for( i in 1:10 ) {
  value = somefunction( i )
  result.frame = rbind( result.frame, c( i, value ) )
}
colnames( result.frame ) <- c( "ID", "Value" )

ここで何百万もの操作について話しているのでない限り、効率について心配する必要はありません。通常、計算は、R がここで行う必要があるこの小さなメモリの再割り当てよりもはるかに集中的です。

さらに、効率も重要であり、必要な行列の正確な行数を最初に計算する必要がある場合は、効率が低下します。

于 2012-10-11T14:43:54.367 に答える