当我有一个以上的测量变量时,我很难想出最优雅、最灵活的方法来将数据从长格式切换到宽格式.

例如,这里有一个长格式的简单数据帧.ID是对象,TIME是时间变量,XY是在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的值转换为包含include 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

(FWIW,我真的不在乎所有的X是先跟在Y后面,还是它们交错排列成X_1Y_1X_2Y_2等等.)

我可以通过两次合并长数据并合并结果来接近这一点,尽管列名需要一些工作,如果我需要在XY之外添加第三个或第四个变量,我需要对其进行调整:

merge(
cast(my.df, ID ~ TIME, value="X"),
cast(my.df, ID ~ TIME, value="Y"),
by="ID", suffixes=c("_X","_Y")
)

似乎reshape2和/或plyr中的一些函数组合应该能够比我的try 更优雅地实现这一点,并且更干净地处理多个度量变量.比如cast(my.df, ID ~ TIME, value=c("X","Y")),这是无效的.但我还没弄明白.

推荐答案

为了像你想要的那样处理多个变量,你需要在转换它之前将你拥有的数据转换为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

根据 comments 进行编辑:

数据帧

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中的一行.

R相关问答推荐

如何通过Exams2黑板对非整数字的问题进行评分

逐行替代引用前一行的for循环

手工PCA上的载体与输出双图不匹配

使用Shiny组合和显示复制和粘贴的数据

提取R中值和列名的所有可能组合

R创建一个数据透视表,计算多个组的百分比

更改绘图上的x轴断点,而不影响风险?

pickerInput用于显示一条或多条geom_hline,这些线在图中具有不同 colored颜色

如何在科学记数法中显示因子

在另一个包中设置断点&S R函数

根据约束随机填充向量的元素

R中的类别比较

Geom_arcbar()中出错:找不到函数";geom_arcbar";

使用来自嵌套列和非嵌套列的输入的PURRR:MAP和dplyr::Mariate

带RStatix的Wilcoxon环内检验

如何为混合模型输出绘制不同的线型?

自定义交互作用图的标签

在ggploy中创建GeV分布时出错

使用函数从R中的列中删除标高

替换在以前工作的代码中有x行&q;错误(geom_sf/gganimate/dow_mark)