37

幅の広いテーブルを長い形式に再形成する必要がありますが、各レコードに複数のフィールドを保持する必要があります。次に例を示します。

dw <- read.table(header=T, text='
 sbj f1.avg f1.sd f2.avg f2.sd  blabla
   A   10    6     50     10      bA
   B   12    5     70     11      bB
   C   20    7     20     8       bC
   D   22    8     22     9       bD
 ')

# Now I want to melt this table, keeping both AVG and SD as separate fields for each measurement, to get something like this:

 #    sbj var avg  sd  blabla
 #     A   f1  10  6     bA
 #     A   f2  50  10    bA
 #     B   f1  12  5     bB
 #     B   f2  70  11    bB
 #     C   f1  20  7     bC
 #     C   f2  20  8     bC
 #     D   f1  22  8     bD
 #     D   f2  22  9     bD

meltとを使用する基本的な知識はありreshapeますが、私の場合、そのような再形成をどのように適用するかは明らかではありません。

4

5 に答える 5

31

reshape適切な引数でこれを行います。

varyingワイド形式では存在するが、ロング形式では複数の行に分割されている列をリストします。 v.names長いフォーマットに相当するものです。2 つの間にマッピングが作成されます。

から?reshape:

また、v.names が明示的に指定されている場合、推測は試行されません。変化する変数の順序は、x.1、y.1、x.2、y.2 のようになっていることに注意してください。

varyingこれらとv.names引数を考えるreshapeと、インデックスがここでドットの前にあることを指定したことを確認するのに十分スマートです (つまり、1.x、1.y、2.x、2.y の順序)。元のデータにはこの順序で列が含まれているため、varying=2:5この例のデータを指定できますが、これは一般的に安全ではないことに注意してください。

と の値を指定するtimesv.names、文字 (既定の引数) で列をreshape分割して、出力に列を作成します。varying.sep

timesvar作成された列で使用される値を指定し、v.namesこれらの値に貼り付けて、結果にマッピングするためのワイド形式の列名を取得します。

最後に、ワイド形式で個々のレコードを識別する列idvarとして指定されsbjます (@thelatemail に感謝)。

reshape(dw, direction='long', 
        varying=c('f1.avg', 'f1.sd', 'f2.avg', 'f2.sd'), 
        timevar='var',
        times=c('f1', 'f2'),
        v.names=c('avg', 'sd'),
        idvar='sbj')

##      sbj blabla var avg sd
## A.f1   A     bA  f1  10  6
## B.f1   B     bB  f1  12  5
## C.f1   C     bC  f1  20  7
## D.f1   D     bD  f1  22  8
## A.f2   A     bA  f2  50 10
## B.f2   B     bB  f2  70 11
## C.f2   C     bC  f2  20  8
## D.f2   D     bD  f2  22  9
于 2014-05-30T01:09:55.967 に答える
8

fの要素から が削除されていることを除いて、これはあなたが望むことをしているようですtime

reshape(dw, idvar = "sbj", varying = list(c(2,4),c(3,5)), v.names = c("ave", "sd"), direction = "long")

    sbj blabla time ave sd
A.1   A     bA    1  10  6
B.1   B     bB    1  12  5
C.1   C     bC    1  20  7
D.1   D     bD    1  22  8
A.2   A     bA    2  50 10
B.2   B     bB    2  70 11
C.2   C     bC    2  20  8
D.2   D     bD    2  22  9
于 2014-05-30T01:18:38.573 に答える
5

ここで利用可能なオプションに追加するには、merged.stack私の「splitstackshape」パッケージからも検討できます。

library(splitstackshape)
merged.stack(dw, var.stubs = c("avg", "sd"), sep = "var.stubs", atStart = FALSE)
#    sbj blabla .time_1 avg sd
# 1:   A     bA     f1.  10  6
# 2:   A     bA     f2.  50 10
# 3:   B     bB     f1.  12  5
# 4:   B     bB     f2.  70 11
# 5:   C     bC     f1.  20  7
# 6:   C     bC     f2.  20  8
# 7:   D     bD     f1.  22  8
# 8:   D     bD     f2.  22  9

".time_1"このように、変数をもう少しクリーンアップすることもできます。

merged.stack(dw, var.stubs = c("avg", "sd"), 
             sep = "var.stubs", atStart = FALSE)[, .time_1 := sub(
               ".", "", .time_1, fixed = TRUE)][]
#    sbj blabla .time_1 avg sd
# 1:   A     bA      f1  10  6
# 2:   A     bA      f2  50 10
# 3:   B     bB      f1  12  5
# 4:   B     bB      f2  70 11
# 5:   C     bC      f1  20  7
# 6:   C     bC      f2  20  8
# 7:   D     bD      f1  22  8
# 8:   D     bD      f2  22  9

atStart = FALSE引数の使用に注意してください。これは、名前の順序が、形状変更関連の関数が好むように見える順序とは少し異なるためです。一般に、次のように、「スタブ」が最初に来て、次に「時間」が来ると予想されます。

dw2 <- dw
setnames(dw2, gsub("(.*)\\.(.*)", "\\2.\\1", names(dw2)))
names(dw2)
# [1] "sbj"    "avg.f1" "sd.f1"  "avg.f2" "sd.f2"  "blabla"

名前がその形式であった場合、ベース Rreshapeと両方ともmerged.stack、より直接的な構文の恩恵を受けます。

merged.stack(dw2, var.stubs = c("avg", "sd"), sep = ".")
reshape(dw2, idvar = c("sbj", "blabla"), varying = 2:5, 
        sep = ".", direction = "long")
于 2014-12-02T11:35:11.000 に答える