我一直试图在r中使用melt()函数来塑造我的数据帧。
这是原作,
group StartX StartY EndX EndY id
18878713 524897 180779 525352 179484 1
18884056 531199 183111 532538 182503 2
我想把它塑造成这个,
group Variable Value id
18878713 524897 180779 1
18884056 531199 183111 2
18878713 525352 179484 1
18884056 532538 182503 2
知道我怎么能这样做吗?谢谢!
答案 0 :(得分:3)
这是使用reshape(...)
的另一个基础R解决方案。
result <- reshape(df,idvar=c(1,6),times=c("Start","End"),v.names=c("X","Y"),
varying=list(c(2,4),c(3,5)),direction="long")
result
# group id time X Y
# 18878713.1.Start 18878713 1 Start 524897 180779
# 18884056.2.Start 18884056 2 Start 531199 183111
# 18878713.1.End 18878713 1 End 525352 179484
# 18884056.2.End 18884056 2 End 532538 182503
您可以使用
删除time
列
result$time <- NULL
如果您坚持使用melt(...)
,这不是真正针对此类问题设计的,那么这是一种方式。
library(reshape2)
m.1 <- melt(df,id=c(1,6),measure=c(2,4),value.name="X")
m.2 <- melt(df,id=c(1,6),measure=c(3,5),value.name="Y")
result <- data.frame(m.1[,-3],Y=m.2$Y)
result
# group id X Y
# 1 18878713 1 524897 180779
# 2 18884056 2 531199 183111
# 3 18878713 1 525352 179484
# 4 18884056 2 532538 182503
答案 1 :(得分:1)
这是使用我的“splitstackshape”包中的merged.stack
的方法:
library(splitstackshape)
merged.stack(mydf, var.stubs = c("X", "Y"), sep = "var.stubs", atStart = FALSE)
# group id .time_1 X Y
# 1: 18878713 1 End 525352 179484
# 2: 18878713 1 Start 524897 180779
# 3: 18884056 2 End 532538 182503
# 4: 18884056 2 Start 531199 183111
通常,期望名称以“可变存根”+“sep”+“时间值”的形式提供(例如,“X.Start”,“X.End”等)。如果没有“sep”,你也可以指定“sep”作为“var.stubs”的正则表达式。 atStart
参数指定是否在变量名称的开头或末尾查找变量存根。
在此示例中,您还可以指定sep = "X$|Y$"
,指示在变量名称的末尾查找“X”或“Y”并将它们组合在一起。在这种情况下,您不会使用atSart
参数。
如果您不想要“.time_1”列,则可以将复合语句与merged.stack
一起使用,但请注意,通过删除它,您的重新整形数据中将丢失信息:
merged.stack(mydf, var.stubs = c("X", "Y"), sep = "X$|Y$")[, .time_1 := NULL][]
# group id X Y
# 1: 18878713 1 525352 179484
# 2: 18878713 1 524897 180779
# 3: 18884056 2 532538 182503
# 4: 18884056 2 531199 183111
merged.stack
也设计得非常快。这是与此基础R reshape
的比较,该数据集被复制为100万行。
## make the dataset 1 million rows
mydf <- do.call(rbind, replicate(500, mydf, FALSE)) ## 1K
mydf <- do.call(rbind, replicate(1000, mydf, FALSE)) ## 1M
mydf$id <- 1:nrow(mydf) ## Row-wise id
funMS <- function() merged.stack(mydf, var.stubs = c("X", "Y"), sep = "X$|Y$")
funR <- function() {
reshape(mydf, idvar = c(1, 6),
times = c("Start", "End"),
v.names = c("X", "Y"),
varying = list(c(2, 4), c(3, 5)),
direction = "long")
}
system.time(funR())
# user system elapsed
# 23.315 0.000 23.224
system.time(funMS())
# user system elapsed
# 2.173 0.000 2.207
答案 2 :(得分:0)
使用新功能融合最近在版本melt.data.table
v1.9.5
中实现的多个列,您可以执行此操作:
require(data.table) ## 1.9.5
melt(dt, measure = patterns("^Start", "^End"))[, variable := NULL][]
# group id value1 value2
# 1: 18878713 1 524897 180779
# 2: 18884056 2 531199 183111
# 3: 18878713 1 525352 179484
# 4: 18884056 2 532538 182503
您可以按照these instructions安装开发版本。