8

次のような構造の非常に大きなデータフレームがあります。

id    x1    x2    x3    y1    y2    y3    z1    z2    z3     v 
 1     2     4     5    10    20    15   200   150   170   2.5
 2     3     7     6    25    35    40   300   350   400   4.2

次のようなデータフレームを作成する必要があります。

id   xsource   xvalue   yvalue   zvalue       v 
 1        x1        2       10      200     2.5
 1        x2        4       20      150     2.5
 1        x3        5       15      170     2.5
 2        x1        3       25      300     4.2
 2        x2        7       35      350     4.2
 2        x3        6       40      400     4.2

reshape パッケージを使用する必要があると確信していますが、必要なものを取得できません。

私たちを手伝ってくれますか?

ありがとう

4

5 に答える 5

8

これがreshape()解決策です。

重要な点はvarying=、長い形式の単一変数に対応するワイド形式の列名のベクトルのリストを引数に取ることができることです。この場合、"x1", "x2", "x3"元のデータ フレームの列は長いデータ フレームの 1 つの列に送信され、列"y1, y2, y3"は 2 番目の列に送信されます。

# Read in the original data, x, from Andrie's answer

res <- reshape(x, direction = "long", idvar = "id",
               varying = list(c("x1","x2", "x3"), 
                              c("y1", "y2", "y3"), 
                              c("z1", "z2", "z3")),
               v.names = c("xvalue", "yvalue", "zvalue"), 
               timevar = "xsource", times = c("x1", "x2", "x3"))
#      id   v xsource xvalue yvalue zvalue
# 1.x1  1 2.5      x1      2     10    200
# 2.x1  2 4.2      x1      3     25    300
# 1.x2  1 2.5      x2      4     20    150
# 2.x2  2 4.2      x2      7     35    350
# 1.x3  1 2.5      x3      5     15    170
# 2.x3  2 4.2      x3      6     40    400

最後に、質問に示されているとおりの結果を得るには、いくつの純粋に表面的な手順が必要です。

res <- res[order(res$id, res$xsource), c(1,3,4,5,6,2)]
row.names(res) <- NULL
res
#   id xsource xvalue yvalue zvalue   v
# 1  1      x1      2     10    200 2.5
# 2  1      x2      4     20    150 2.5
# 3  1      x3      5     15    170 2.5
# 4  2      x1      3     25    300 4.2
# 5  2      x2      7     35    350 4.2
# 6  2      x3      6     40    400 4.2
于 2012-01-13T18:17:59.193 に答える
2

これは、 tidy datareshape2に関する私の論文で詳細に説明されている1 つのアプローチです。

ステップ 1: すでに列にある変数を特定します。この場合: id、および v。これらは、溶解する変数です。

library(reshape2)
xm <- melt(x, c("id", "v"))

ステップ 2: 現在 1 つの列に結合されている変数を分割します。この場合、それは source (文字部分) と rep (整数部分) です。

stringrこれを行うには多くの方法があります。パッケージで文字列抽出を使用します

library(stringr)
xm$source <- str_sub(xm$variable, 1, 1)
xm$rep <- str_sub(xm$variable, 2, 2)
xm$variable <- NULL

ステップ 3: 現在行にある変数を再配置しますが、列には必要です。

dcast(xm, ... ~ source)

#   id   v rep x  y   z
# 1  1 2.5     1 2 10 200
# 2  1 2.5     2 4 20 150
# 3  1 2.5     3 5 15 170
# 4  2 4.2     1 3 25 300
# 5  2 4.2     2 7 35 350
# 6  2 4.2     3 6 40 400
于 2012-01-14T13:13:23.873 に答える
1

誰かが私が間違っていることを証明してください。しかし、reshapeパッケージまたは基本reshape関数のいずれかを使用してこの問題を解決するのは簡単ではないと思います。

lapplyただし、とを使用するのは簡単do.callです。

データを複製します。

x <- read.table(text="
id    x1    x2    x3    y1    y2    y3    z1    z2    z3     v 
1     2     4     5    10    20    15   200   150   170   2.5
2     3     7     6    25    35    40   300   350   400   4.2
", header=TRUE)

分析を行う

chunks <- lapply(1:nrow(x), 
    function(i)cbind(x[i, 1], 1:3, matrix(x[i, 2:10], ncol=3), x[i, 11]))
res <- do.call(rbind, chunks)
colnames(res) <- c("id", "source", "x", "y", "z", "v")
res

     id source x y  z   v  
[1,] 1  1      2 10 200 2.5
[2,] 1  2      4 20 150 2.5
[3,] 1  3      5 15 170 2.5
[4,] 2  1      3 25 300 4.2
[5,] 2  2      7 35 350 4.2
[6,] 2  3      6 40 400 4.2
于 2012-01-13T16:40:00.467 に答える
0

reshapeGUI パッケージを使用してみてください。plyr パッケージと reshape2 パッケージを利用し、使いやすいインターフェイスを提供して、実行前にリシェイプをプレビューできます。また、実行中のリシェイプのコードも提供されるので、スクリプトに貼り付けて再現性を高めたり、reshape2 での Melt コマンドと Cast コマンドの使用方法を学習したりできます。これは、改造忍者ではない人にとって、このような複雑なデータ操作の優れた松葉杖です。

于 2012-07-12T14:13:02.613 に答える