5

次の形式の大きな data.frame (20000 以上のエントリ) があります。

id  D1      D2
1   0.40    0.21
1   0.00    0.00
1   0.53    0.20
2   0.17    0.17
2   0.25    0.25
2   0.55    0.43

各 ID は 3 ~ 20 回複製できます。重複した行を新しい列にマージしたいので、新しい data.frame は次のようになります。

id  D1      D2      D3      D4      D5      D6
1   0.40    0.21    0.00    0.00    0.53    0.20
2   0.17    0.17    0.25    0.25    0.55    0.43

以前に plyr で data.frames を操作したことがありますが、この問題にどのように対処すればよいかわかりません。どんな助けでも大歓迎です.Thanks.

4

1 に答える 1

8

最良のオプションは、「reshape2」から使用することmeltですdcast。ただし、そのオプションにジャンプする前に、他に利用できるものを見てみましょう。


「id」あたりの行数が不均衡だとおっしゃっています。それは、きちんとした長方形に入れるのがやや難しいでしょうdata.frame

いくつかの例を次に示します。

バランスの取れたデータ: 「id」ごとに 3 行

mydf <- structure(list(id = c(1, 1, 1, 2, 2, 2), 
                       D1 = c(0.4, 0, 0.53, 0.17, 0.25, 0.55), 
                       D2 = c(0.21, 0, 0.2, 0.17, 0.25, 0.43)), 
                  .Names = c("id", "D1", "D2"), row.names = c(NA, 6L), 
                  class = "data.frame")
mydf
#   id   D1   D2
# 1  1 0.40 0.21
# 2  1 0.00 0.00
# 3  1 0.53 0.20
# 4  2 0.17 0.17
# 5  2 0.25 0.25
# 6  2 0.55 0.43

このようなデータを使用すると、次のように使用できますaggregate

do.call(data.frame, aggregate(. ~ id, mydf, as.vector))
#   id D1.1 D1.2 D1.3 D2.1 D2.2 D2.3
# 1  1 0.40 0.00 0.53 0.21 0.00 0.20
# 2  2 0.17 0.25 0.55 0.17 0.25 0.43

不均衡なデータ: いくつかの回避策

「id = 2」に 4 番目の値を追加した場合、aggregateここでは機能しません。

mydf[7, ] <- c(2, .44, .33)
do.call(data.frame, aggregate(. ~ id, mydf, as.vector))
# Error in data.frame(`0` = c(0.4, 0, 0.53), `1` = c(0.17, 0.25, 0.55, 0.44 : 
#   arguments imply differing number of rows: 3, 4

list結果vectorの sだけを取得するのが最善の場合があります。

lapply(split(mydf[-1], mydf[[1]]), function(x) unlist(x, use.names=FALSE))
# $`1`
# [1] 0.40 0.00 0.53 0.21 0.00 0.20
# 
# $`2`
# [1] 0.17 0.25 0.55 0.44 0.17 0.25 0.43 0.33
# 

または、長方形に固執する場合は、「plyr」などの不均衡なデータに対するdata.frameいくつかのツールのいずれかを調べます。rbindrbind.fill

library(plyr)
rbind.fill(lapply(split(mydf[-1], mydf[[1]]), 
                  function(x) data.frame(t(unlist(x, use.names=FALSE)))))
#     X1   X2   X3   X4   X5   X6   X7   X8
# 1 0.40 0.00 0.53 0.21 0.00 0.20   NA   NA
# 2 0.17 0.25 0.55 0.44 0.17 0.25 0.43 0.33

不均衡なデータ: より直接的なアプローチ

または、次のように「reshape2」からmeltandを使用できます。dcast

library(reshape2)
x <- melt(mydf, id.vars = "id")
## ^^ That's not enough information for `dcast`
##    We need a "time" variable too, so use `ave`
##      to create one according to the number of
##      values per ID.
x$time <- ave(x$id, x$id, FUN = seq_along)
## ^^ I would probably actually stop at this point.
##    Long data with proper ID and "time" values
##      tend to be easier to work with and many
##      other functions in R work more nicely with
##      this long data format.
dcast(x, id ~ time, value.var = "value")
#   id    1    2    3    4    5    6    7    8
# 1  1 0.40 0.00 0.53 0.21 0.00 0.20   NA   NA
# 2  2 0.17 0.25 0.55 0.44 0.17 0.25 0.43 0.33
于 2013-07-27T04:51:07.733 に答える