1

我一直在尝试在 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

知道我该怎么做吗?谢谢!

4

3 回答 3

3

这是另一个使用reshape(...).

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
于 2014-11-15T19:38:13.360 回答
1

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 
于 2014-11-16T06:08:38.407 回答
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

您可以按照这些说明安装开发版本。

于 2015-02-28T07:35:42.020 回答