使用Reforme()或melt()将数据帧从宽数据转换为长数据的更优雅的方式
我正在寻找一种更优雅的方式,通过使用melt(Reforme2)或Reformate函数来重塑我的数据帧 假设我有一个简单的数据框,如下所示:使用Reforme()或melt()将数据帧从宽数据转换为长数据的更优雅的方式,r,reshape,R,Reshape,我正在寻找一种更优雅的方式,通过使用melt(Reforme2)或Reformate函数来重塑我的数据帧 假设我有一个简单的数据框,如下所示: d<-data.frame("PID"=factor(c(1,1,1,2,2,2)), "Cue1"=factor(c(1,2,3,1,2,3)), "Cue2"=factor(c(5,5,5,5,5,5))) 不幸的是,互联网上关于重塑的大多数示例都讨论了以下示例(在我的案例中是非首选示例
d<-data.frame("PID"=factor(c(1,1,1,2,2,2)),
"Cue1"=factor(c(1,2,3,1,2,3)),
"Cue2"=factor(c(5,5,5,5,5,5)))
不幸的是,互联网上关于重塑的大多数示例都讨论了以下示例(在我的案例中是非首选示例):
但我需要前一个
提前感谢您的建议。最简单的方法是使用
melt
。这与初始数据帧(d1
)相同,除非触发器的确切顺序很重要
library(reshape2)
d2 <- melt(d, id="PID", value.name="trigger")[,c(3,1)]
> d2
trigger PID
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 5 1
8 5 1
9 5 1
10 5 2
11 5 2
12 5 2
通过按触发器排序,您可以看到它们都是相同的
> d2[order(d2$trigger),]
trigger PID
1 1 1
4 1 2
2 2 1
5 2 2
3 3 1
6 3 2
7 5 1
8 5 1
9 5 1
10 5 2
11 5 2
12 5 2
> d1[order(d1$trigger),]
trigger PID
1 1 1
7 1 2
3 2 1
9 2 2
5 3 1
11 3 2
2 5 1
4 5 1
6 5 1
8 5 2
10 5 2
12 5 2
最简单的方法是使用
melt
。这与初始数据帧(d1
)相同,除非触发器的确切顺序很重要
library(reshape2)
d2 <- melt(d, id="PID", value.name="trigger")[,c(3,1)]
> d2
trigger PID
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 5 1
8 5 1
9 5 1
10 5 2
11 5 2
12 5 2
通过按触发器排序,您可以看到它们都是相同的
> d2[order(d2$trigger),]
trigger PID
1 1 1
4 1 2
2 2 1
5 2 2
3 3 1
6 3 2
7 5 1
8 5 1
9 5 1
10 5 2
11 5 2
12 5 2
> d1[order(d1$trigger),]
trigger PID
1 1 1
7 1 2
3 2 1
9 2 2
5 3 1
11 3 2
2 5 1
4 5 1
6 5 1
8 5 2
10 5 2
12 5 2
如果您只是在寻找使用melt的单层衬里,以下是一种方法(保留所需的订单):
如果您只是在寻找使用melt的单层衬里,以下是一种方法(保留所需的订单):
我认为“优雅”是主观的,但是如果你在寻找另一种选择,你可以从我的“SPLITSTACKFILE”包中考虑<代码>合并。但是,为了使
merged.stack
正常工作,您的ID变量必须是唯一的。为此,您可以使用getanID
(也可以从“splitstackshape”中):
另外两列将是:
,由.id
创建。此列与“PID”列组合时将创建唯一的ID李>getanID
,它是“叠加”步骤的结果,指示值来自哪个“提示”列(在本例中,在1和2之间循环表示“提示1”和“提示2”).time\u 1
merged.stack
正常工作,您的ID变量必须是唯一的。为此,您可以使用getanID
(也可以从“splitstackshape”中):
另外两列将是:
,由.id
创建。此列与“PID”列组合时将创建唯一的ID李>getanID
,它是“叠加”步骤的结果,指示值来自哪个“提示”列(在本例中,在1和2之间循环表示“提示1”和“提示2”).time\u 1
代码中读取
[,c(“PID”,“Cue”),with=FALSE]
的部分意味着只向我们显示这两列(因为这似乎就是您感兴趣的内容)。您所说的优雅是什么意思?在紧凑性方面?在我的解决方案中,我必须为PID添加一个新列,再加上另一个列来标识列中的值是来自cue1还是来自CUE2(在上面的示例中未显示)。我认为已经有了一种更简洁、更简单的方法。请看我的答案。希望它能满足你的一些期望:)你说的优雅是什么意思?在紧凑性方面?在我的解决方案中,我必须为PID添加一个新列,再加上另一个列来标识列中的值是来自cue1还是来自CUE2(在上面的示例中未显示)。我认为已经有了一种更简洁、更简单的方法。请看我的答案。希望它能满足你的一些期望:)谢谢你的回答。这几乎是我想要的,也许我解释得很模糊,所以我试着纠正自己。更具体地说,行的确切顺序很重要。d1中新的长列(d1$trigger)应该以d[1,2]开始,然后是d[1,3],然后是d[2,2],d[2,3],d[3,2],d[4,2],d[4,3],d[5,2],d[5,3],d[6,2]和d[6,3]……因此在最后,我将分别对PID 1和PID 2使用所有触发器。在您的解决方案中,PID是交替的。如果我使用d3[order(d3$PID),],那么触发器的顺序将丢失。为什么保持准确的顺序如此重要?数据是相同的。你想做什么这么严格?我想比较我发送的触发器和我收到的触发器,以确保它被正确发送/解释。你不能也对“已发送”触发器进行排序,然后进行比较吗?如果您能提供一个完整的比较示例以及当前失败的地方,也许这将是最好的。然后,如果我使用上面的代码,也就是我在提问时编写的代码,会更容易。我可以转换df并创建一个向量,然后简单地比较这些值。我认为对于这种重塑过程有一个简洁的解决方案。谢谢你的回答。这几乎是我想要的,也许我解释得很模糊,所以我试着纠正自己。更具体地说,行的确切顺序很重要。d1中新的长列(d1$trigger)应该以d[1,2]开始,然后是d[1,3],然后是d[2,2],d[2,3],d[3,2],d[4,2],d[4,3],d[5,2],d[5,3],d[6,2]和d[6,3]……因此在最后,我将分别对PID 1和PID 2使用所有触发器。在您的解决方案中,PID是交替的。如果我使用d3[order(d3$PID),],那么触发器的顺序将丢失。为什么保持准确的顺序如此重要?数据是相同的。你想做什么这么严格?我想比较我发送的触发器和我收到的触发器,以确保它被正确发送/解释。你不能也对“已发送”触发器进行排序,然后进行比较吗?如果你能提供一个完整的例子来说明这个比较,以及它目前失败的地方,也许这将是最好的
d3 <- reshape(d, direction="long",
varying=list(names(d)[2:3]),
v.names="trigger",
idvar="PID",
new.row.names=seq(12))[,c(3,1)]
> d2[order(d2$trigger),]
trigger PID
1 1 1
4 1 2
2 2 1
5 2 2
3 3 1
6 3 2
7 5 1
8 5 1
9 5 1
10 5 2
11 5 2
12 5 2
> d1[order(d1$trigger),]
trigger PID
1 1 1
7 1 2
3 2 1
9 2 2
5 3 1
11 3 2
2 5 1
4 5 1
6 5 1
8 5 2
10 5 2
12 5 2
# assume DF is your data frame
DF_new = data.frame(trigger = melt(t(DF[,2:3]))[,3], PID = rep(DF[,1], each=2))
DF_new
# trigger PID
# 1 1 1
# 2 5 1
# 3 2 1
# 4 5 1
# 5 3 1
# 6 5 1
# 7 1 2
# 8 5 2
# 9 2 2
# 10 5 2
# 11 3 2
# 12 5 2
library(splitstackshape)
packageVersion("splitstackshape")
# [1] ‘1.4.2’
merged.stack(getanID(d, "PID"), var.stubs = "Cue",
sep = "var.stubs")[, c("PID", "Cue"), with = FALSE]
# PID Cue
# 1: 1 1
# 2: 1 5
# 3: 1 2
# 4: 1 5
# 5: 1 3
# 6: 1 5
# 7: 2 1
# 8: 2 5
# 9: 2 2
# 10: 2 5
# 11: 2 3
# 12: 2 5
## factor levels retained as desired
str(.Last.value)
# Classes ‘data.table’ and 'data.frame': 12 obs. of 2 variables:
# $ PID: Factor w/ 2 levels "1","2": 1 1 1 1 1 1 2 2 2 2 ...
# $ Cue: Factor w/ 4 levels "1","2","3","5": 1 4 2 4 3 4 1 4 2 4 ...
# - attr(*, "sorted")= chr "PID"
# - attr(*, ".internal.selfref")=<externalptr>
merged.stack(getanID(d, "PID"), var.stubs = "Cue", sep = "var.stubs")