当我要携带多个度量变量时,我很难找出将数据从长格式转换为宽格式的最优雅和灵活的方法。
例如,这是一个长格式的简单数据帧。ID
是主题,TIME
是时间变量,X
和Y
是TIME
的ID
测量值
> my.df <- data.frame(ID=rep(c("A","B","C"), 5), TIME=rep(1:5, each=3), X=1:15, Y=16:30)
> my.df
ID TIME X Y
1 A 1 1 16
2 B 1 2 17
3 C 1 3 18
4 A 2 4 19
5 B 2 5 20
6 C 2 6 21
7 A 3 7 22
8 B 3 8 23
9 C 3 9 24
10 A 4 10 25
11 B 4 11 26
12 C 4 12 27
13 A 5 13 28
14 B 5 14 29
15 C 5 15 30
如果我只想将TIME
的值转换为包含X
的列标题,我知道我可以使用reshape
包中的cast()
(或reshape2
中的dcast()
):
> cast(my.df, ID ~ TIME, value="X")
ID 1 2 3 4 5
1 A 1 4 7 10 13
2 B 2 5 8 11 14
3 C 3 6 9 12 15
但我真正想做的也是引入Y
作为另一个度量变量,并让列名同时反映度量变量名称和时间值:
ID X_1 X_2 X_3 X_4 X_5 Y_1 Y_2 Y_3 Y_4 Y_5
1 A 1 4 7 10 13 16 19 22 25 28
2 B 2 5 8 11 14 17 20 23 26 29
3 C 3 6 9 12 15 18 21 24 27 30
(顺便说一句,我真的不在乎所有的X
是不是都跟在Y
后面,或者它们是不是像X_1
,Y_1
,X_2
,Y_2
等一样交错。)
我可以通过转换两次长数据并合并结果来接近这一点,尽管列名需要一些工作,如果我需要在X
和Y
之外添加第三个或第四个变量,我将需要调整它
merge(
cast(my.df, ID ~ TIME, value="X"),
cast(my.df, ID ~ TIME, value="Y"),
by="ID", suffixes=c("_X","_Y")
)
似乎reshape2
和/或plyr
中的一些函数组合应该能够比我的尝试更优雅地做到这一点,以及更干净地处理多个度量变量。像cast(my.df, ID ~ TIME, value=c("X","Y"))
这样的东西,它是无效的。但我一直没能弄明白。
发布于 2012-05-15 03:17:44
为了像你想要的那样处理多个变量,你需要在对数据进行类型转换之前对它进行melt
。
library("reshape2")
dcast(melt(my.df, id.vars=c("ID", "TIME")), ID~variable+TIME)
这给了我们
ID X_1 X_2 X_3 X_4 X_5 Y_1 Y_2 Y_3 Y_4 Y_5
1 A 1 4 7 10 13 16 19 22 25 28
2 B 2 5 8 11 14 17 20 23 26 29
3 C 3 6 9 12 15 18 21 24 27 30
基于注释进行编辑:
数据帧
num.id = 10
num.time=10
my.df <- data.frame(ID=rep(LETTERS[1:num.id], num.time),
TIME=rep(1:num.time, each=num.id),
X=1:(num.id*num.time),
Y=(num.id*num.time)+1:(2*length(1:(num.id*num.time))))
给出不同的结果(所有条目都是2),因为ID
/TIME
组合不指示唯一行。实际上,每种ID
/TIME
组合都有两行。reshape2
假设每个可能的变量组合都有一个值,如果有多个条目,则将应用汇总函数来创建单个变量。这就是为什么会有这样的警告
Aggregation function missing: defaulting to length
如果你添加另一个变量来打破这种冗余,你就可以得到一些有用的东西。
my.df$cycle <- rep(1:2, each=num.id*num.time)
dcast(melt(my.df, id.vars=c("cycle", "ID", "TIME")), cycle+ID~variable+TIME)
这之所以有效,是因为cycle
/ID
/time
现在在my.df
中唯一地定义了一行。
发布于 2012-05-15 03:18:55
reshape(my.df,
idvar = "ID",
timevar = "TIME",
direction = "wide")
给出
ID X.1 Y.1 X.2 Y.2 X.3 Y.3 X.4 Y.4 X.5 Y.5
1 A 1 16 4 19 7 22 10 25 13 28
2 B 2 17 5 20 8 23 11 26 14 29
3 C 3 18 6 21 9 24 12 27 15 30
发布于 2015-03-19 23:37:32
使用data.table_1.9.5
,这可以在没有melt
的情况下完成,因为它可以处理多个value.var
列。您可以从here
安装它
library(data.table)
dcast(setDT(my.df), ID~TIME, value.var=c('X', 'Y'))
# ID 1_X 2_X 3_X 4_X 5_X 1_Y 2_Y 3_Y 4_Y 5_Y
#1: A 1 4 7 10 13 16 19 22 25 28
#2: B 2 5 8 11 14 17 20 23 26 29
#3: C 3 6 9 12 15 18 21 24 27 30
https://stackoverflow.com/questions/10589693
复制相似问题