我在数据框中有一些数据,格式如下:
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
...
答案 0 :(得分: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
答案 1 :(得分:4)
在@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
答案 2 :(得分:3)
stack
你是stack
是可能的,但你可能错过了stack
文档中的一个关键界线:
请注意,堆栈适用于向量(由is.vector确定):非向量列(例如,因子)将被忽略(带有来自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列的行。有关如何执行此操作,请参阅here。
有了这些信息,我们可以使用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
和朋友有更好的解决方案时,你想要完成我所展示的所有工作;)
您还可以从我的“splitstackshape”软件包中查看merged.stack
:
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
或者来自“tidyr”的gather
:
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