4

次の形式のデータフレームにいくつかのデータがあります。

A  B  C  V1  V2  V3
1  1  1  x   y   z
1  1  2  a   b   c
...

ここで、A、B、Cは因子であり、A、B、Cの組み合わせは行ごとに一意です。

次のような形式を実現するには、いくつかの列を係数に変換する必要があります。

A  B  C  V  val
1  1  1  V1 x
1  1  1  V2 y
1  1  1  V3 z
1  1  2  V1 a
1  1  2  V2 b
1  1  2  V2 c
...

これは、スタックとxtabsの逆の両方に関連しているようですが、特定の列のみを「スタック」するように指定する方法がわかりません。

4

3 に答える 3

5

そして、@ AnandaMahtoがここに来て、彼の基本reshape的な解決策を提供する前に、これが私の試みです:

dat <- read.table(text = 'A  B  C  V1  V2  V3
1  1  1  x   y   z
1  1  2  a   b   c',header= T)

expandvars <- c("V1","V2","V3")

datreshape <- reshape(dat,
                   idvar=c("A","B","C"),
                   varying=list(expandvars),
                   v.names=c("val"),
                   times=expandvars,
                   direction="long")

> datreshape
         A B C time val
1.1.1.V1 1 1 1   V1   x
1.1.2.V1 1 1 2   V1   a
1.1.1.V2 1 1 1   V2   y
1.1.2.V2 1 1 2   V2   b
1.1.1.V3 1 1 1   V3   z
1.1.2.V3 1 1 2   V3   c
于 2013-02-01T02:55:00.197 に答える
4

reshape2パッケージを使用する

dat <- read.table(text = 'A  B  C  V1  V2  V3
1  1  1  x   y   z
1  1  2  a   b   c',header= T)
library(reshape2)
melt(dat,id.vars = c('A','B','C'))
 A B C variable value
1 1 1 1       V1     x
2 1 1 2       V1     a
3 1 1 1       V2     y
4 1 1 2       V2     b
5 1 1 1       V3     z
6 1 1 2       V3     c
于 2013-02-01T02:28:14.727 に答える
3

stack

あなたはその可能性があるのは正しいですstackが、おそらく次のドキュメントの重要な行を見逃しているでしょうstack

スタックはベクトルに適用されることに注意してください(is.vectorによって決定されます):非ベクトル列(たとえば、factors)は無視されます(R 2.15.0からの警告付き)。

では、どのように進めますか?

データは次のとおりです。

dat <- read.table(text = 'A  B  C  V1  V2  V3
    1  1  1  x   y   z
    1  1  2  a   b   c',header= T)

ここでは、係数を次のように変換しas.characterます。

dat[sapply(dat, is.factor)] = lapply(dat[sapply(dat, is.factor)], as.character)

どの列を指定するかは次のstackとおりです。

stack(dat[4:6])
#   values ind
# 1      x  V1
# 2      a  V1
# 3      y  V2
# 4      b  V2
# 5      z  V3
# 6      c  V3

ただし、列1〜3の行を「拡張」する必要があります。その方法については、こちらをご覧ください。

この情報を使用cbindして、目的の結果を取得できます。

cbind(dat[rep(row.names(dat), 3), 1:3], stack(dat[4:6]))
#     A B C values ind
# 1   1 1 1      x  V1
# 2   1 1 2      a  V1
# 1.1 1 1 1      y  V2
# 2.1 1 1 2      b  V2
# 1.2 1 1 1      z  V3
# 2.2 1 1 2      c  V3

xtabs

あなたもxtabsそうですが、それは可能性が高いと思われますが、実際にはあなたが提供したものとはxtabsのことを期待しています。つまり、数式を指定すると、左側の項目が数値であり、右側の項目が要素であると想定されます。したがって、データが交換された場合は、確かにを使用できます。xtabs

matchこれがデモンストレーションです(これは、 「文字」から「数字」への簡単な「文字」を使用できる簡単な例を使用しているためにのみ機能します)。

dat2 <- dat # Make a copy of "dat"
# Swap out dat 4-6 with numbers
dat2[4:6] <- lapply(dat2[4:6], function(x) match(x, letters))
# Swap out dat 1-3 with letters
dat2[1:3] <- lapply(dat2[1:3], function(x) letters[x])
# Our new "dat"
dat2
#   A B C V1 V2 V3
# 1 a a a 24 25 26
# 2 a a b  1  2  3
data.frame(xtabs(cbind(V1, V2, V3) ~ A + B + C, dat2))
#   A B C Var4 Freq
# 1 a a a   V1   24
# 2 a a b   V1    1
# 3 a a a   V2   25
# 4 a a b   V2    2
# 5 a a a   V3   26
# 6 a a b   V3    3

言い換えれば、ツールの選択は潜在的に正しい可能性がありますが、データもツールが期待する形式である必要があります。

しかし、より良い解決策が友人や友人と一緒に存在するときに、なぜあなたが私が示したすべての仕事をしたいと思うのかわかりませんreshape;)


非常に遅い更新...

merged.stack私の「splitstackshape」パッケージからも見ることができます:

library(splitstackshape)
merged.stack(dat, var.stubs = "V", sep = "NoSep")
#    A B C .time_1 V
# 1: 1 1 1      V1 x
# 2: 1 1 1      V2 y
# 3: 1 1 1      V3 z
# 4: 1 1 2      V1 a
# 5: 1 1 2      V2 b
# 6: 1 1 2      V3 c

またはgather「tidyr」から:

library(dplyr)
library(tidyr)
# gather(dat, var, val, V1:V3)
dat %>% gather(var, val, V1:V3) 
#   A B C var val
# 1 1 1 1  V1   x
# 2 1 1 2  V1   a
# 3 1 1 1  V2   y
# 4 1 1 2  V2   b
# 5 1 1 1  V3   z
# 6 1 1 2  V3   c
于 2013-02-01T04:56:03.043 に答える