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