2

巨大なデータフレーム(約12.000ケース)を再構築しようとしています。古いデータフレームでは、1人が1行で、約250列(たとえば、Person 1、test A1、testA2、testBなど)があり、すべての結果が必要です。テストAの(全体で1〜10 A、1列にその人の24項目(AY)があるため、1人は24列10行になります。項目AYが開始する前に固定データフレーム部分もあります(個人年齢、性別などの情報)をそのままにしておきたい(fixdata)。関数/ループは30ケース(事前に試した)で動作しますが、12.000の場合は、24時間近く計算中です。なぜ何かアイデアはありますか?

restructure <- function(data, firstcol, numcol, numsets){
    out <- data.frame(t(rep(0, (firstcol-1)+ numcol)) )
    names(out) <- names(daten[0:(firstcol+numcol-1)])
      for(i in 1:nrow(daten)){
         fixdata <- (daten[i, 1:(firstcol-1)])

          for (j in (seq(firstcol, ((firstcol-1)+ numcol* numsets), by = numcol))){
              flexdata <- daten[i, j:(j+numcol-1)]
              tmp <- cbind(fixdata, flexdata)
              names(tmp) <- names(daten[0:(firstcol+numcol-1)])
              out <- rbind(out,tmp)
          }  
      }
    out <- out[2:nrow(out),]
    return(out)
}

前もって感謝します!

4

3 に答える 3

5

理由を考えてください:各反復であなたrbindに。outこれは、outが大きくなるにつれて各反復に時間がかかります。したがって、データセットの増加に伴い、実行時間は直線的に大きくなることを期待する必要があります。

だから、アンドリーが言うように、あなたは見ることができますmelt

または、コアRでそれを行うことができますstack。次に、固定部分を自分で結果に結合する必要があります(固定列を次のように繰り返す必要があります)each = n.var.cols

3番目の選択肢はarray2df、パッケージarrayhelpersからのものです。

于 2011-11-04T12:05:33.147 に答える
1

私は他の人たちに同意しreshape2plyrパッケージを調べて、別の方向に少し追加したいと思います。特に、、meltはあなたcastdcast助けるかもしれません。さらに、スマートな列名を利用すると役立つ場合があります。例:

As<-grep("^testA",names(yourdf))
# returns a vector with the column position of all testA1 through 10s.

さらに、on test#とtest typeの2つの次元を「費やした」場合、data.frameその人には明らかに何も残っていません。確かに、それらをIDで識別します。これにより、プロット時に美的感覚を加えることができますが、実行する内容によっては、それらをに格納することもできますlist。したがって、すべての人のdata.frameを持つ人のリストができあがります。あなたが何をしようとしているのかわかりませんが、それでもこれが役立つことを願っています。

于 2011-11-04T17:03:22.197 に答える
0

たぶん、データコンポーネントを再形成するためのplyrまたは他の関数を取得していません。もっと直接的で低レベルなものはどうですか。現在、A1、A2、A3 ... A10、B1-B10などの行が1つしかない場合は、データフレームからその塊を抽出します。列11〜250を推測し、それを作成します。必要な形状を切り取り、元に戻します。

yDat <- data[, 11:250]
yDF <- lapply( 1:nrow(data), function(i) matrix(yDat[i,], ncol = 24) )
yDF <- do.call(rbind, y) #combine the list of matrices returned above into one
yDF <- data.frame(yDF) #get it back into a data.frame
names(yDF) <- LETTERS[1:24] #might as well name the columns

これは、データの大部分を希望の形にするための最速の方法です。関数が行ったのは、lapply各行にディメンション属性を追加して希望の形にした後、それらをリストとして返し、後続の行でマッサージすることだけでした。ただし、メインのdata.frameからのID情報は含まれていません。最初の10列の各行を10回複製する必要があります。または、便利な機能mergeを使用してそれを支援することもできます。最初の10行にすでにある共通の列を新しいdata.frameの列の1つにして、それらをマージします。

yInfo <- data[, 1:10]
ID <- yInfo$ID
yDF$ID <- rep( yInfo$ID, each = 10 )
newDat <- merge(yInfo, yDF)

これで完了です...ほとんどの場合、新しい行に名前を付ける追加の列を作成することをお勧めします

newDat$condNum <- rep(1:10, nrow(newDat)/10)

これは非常に高速に実行されるコードになります。data.frameは実際にはそれほど大きくはなく、上記の多くは数秒で実行されます。

これは、Rのデータをどのように考えるかです。これの大部分を処理する便利な関数がないわけではありませんが、可能な限りループを回避するようにこれを行う必要があります。技術的には、上記で起こったことlapplyは、最初に使用されたループが1つだけでした。そのループにもほとんどありませんでした(使用するときはコンパクトである必要があります)。あなたはスカラーコードで書いています、そしてそれはRで非常に遅いです...あなたがそれをしている間あなたが本当にメモリを乱用してデータを増やしていなかったとしても。さらに、ある種のループを常に回避できるとは限りませんが、ほとんどの場合、ネストされたループを回避できることに注意してください。これは、最大の問題の1つです。

(このコードの問題をよりよく理解するためにこれを読んでください...あなたはそこで大きなエラーのほとんどを犯しました)

于 2011-11-04T15:36:49.830 に答える