4

コースとユーザー用に2つのID列を持つ大きな古いデータフレームがあり、さらに分析/サブセット化を行うために、コースごとに1つのデータフレームに分割する必要がありました。個々のコースデータフレームのそれぞれからかなりの数の行を削除した後、それらを元に戻す必要があります。

私はそれを使用して分割しました、あなたはそれを推測しましたsplit、そしてそれは私がそれを必要としていたのとまったく同じように機能しました。しかし、分割解除は思ったより大変でした。Rのドキュメントには「unsplitの効果が逆転する」と書かれてsplitいますが、これまでのWebでの私の読書は、分割リストの要素自体がデータフレームである場合はそうではないことを示唆しています。

変更したdfsに再参加するにはどうすればよいですか?

4

4 に答える 4

13

これはのための場所ですdo.call。単に呼び出すだけdf <- rbind(split.df)で、奇妙で役に立たないリストオブジェクトが生成さdo.call("rbind", split.df)れますが、探している結果が得られるはずです。

于 2012-11-07T19:25:23.847 に答える
5

unsplit()あなたが説明した一般的な状況では機能します/機能するように見えますが、このように分割されたデータフレームから行を削除する特定の状況では機能しません。

検討

> spl <- split(mtcars, mtcars$cyl)
> str(spl, max = 1)
List of 3
 $ 4:'data.frame':  11 obs. of  11 variables:
 $ 6:'data.frame':  7 obs. of  11 variables:
 $ 8:'data.frame':  14 obs. of  11 variables:
> str(unsplit(spl, f = mtcars$cyl))
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

ご覧のとおりunsplit()、分割を元に戻すことができます。ただし、分割されたデータ フレームがさらに処理され、行を削除するように変更された場合、分割リスト内のデータ フレームの行の総数と、元のデータ フレームの分割に使用された変数との間に不一致が生じます。

元のデータ フレームの分割に使用される変数を作成するために必要な変更を知っているか、計算できる場合は、unsplit()展開できます。これは簡単ではない可能性が高いですが。

@Andrew Sannierが言及しているように、一般的な解決策はdo.call(rbind, ...)イディオムです:

> spl <- split(mtcars, mtcars$cyl)
> str(do.call(rbind, spl))
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  22.8 24.4 22.8 32.4 30.4 33.9 21.5 27.3 26 30.4 ...
 $ cyl : num  4 4 4 4 4 4 4 4 4 4 ...
 $ disp: num  108 146.7 140.8 78.7 75.7 ...
 $ hp  : num  93 62 95 66 52 65 97 66 91 113 ...
 $ drat: num  3.85 3.69 3.92 4.08 4.93 4.22 3.7 4.08 4.43 3.77 ...
 $ wt  : num  2.32 3.19 3.15 2.2 1.61 ...
 $ qsec: num  18.6 20 22.9 19.5 18.5 ...
 $ vs  : num  1 1 1 1 1 1 1 1 0 1 ...
 $ am  : num  1 0 0 1 1 1 0 1 1 1 ...
 $ gear: num  4 4 4 4 4 4 3 4 5 5 ...
 $ carb: num  1 2 2 1 2 1 1 1 2 2 ...
于 2012-11-07T19:50:32.453 に答える
2

ベース R 以外では、次のことも考慮してください。

  • data.table::rbindlist()結果の副作用はdata.table
  • dplyr::bind_rows()やや紛らわしい名前にもかかわらず、リスト全体で行をバインドします
于 2016-08-31T11:37:06.807 に答える
1

Andrew Sannier による答えは機能しますが、行名が変更されるという副作用があります。rbindリスト名を追加します。たとえば、「Datsun 710」は「4.Datsun 710」になります。unnameこの問題を回避するために間に使用できます。

完全な例:

mtcars_reorder = mtcars[order(mtcars$cyl), ] #reorder based on cyl first
l1 = split(mtcars_reorder, mtcars_reorder$cyl) #split by cyl
l1 = unname(l1) #remove list names
l2 = do.call(what = "rbind", l1) #unsplit
all(l2 == mtcars_reorder) #check if matches
#> TRUE
于 2016-03-11T23:23:09.307 に答える