merged.stack
这是我的“splitstackshape”包中使用的一种方法:
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
也被设计得非常快。reshape
这是与复制为 100 万行的数据集上的基本 R 的比较。
## 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