如何将时间表数据帧转换为长格式?

时间:2017-12-13 12:47:58

标签: r

简介:这是一个我想问的问题,但最终解决了自己。我希望答案可能对某人有用,所以我将其作为一个已回答的问题留在这里。

我有火车的时间表数据集。我想将其转换为长格式。

这就是我的数据:

  Train    AMS-A     AMS-D      UTR-A     UTR-D  
 ------- --------- --------- ----------- ------- 
  1       03:00     03:10     06:40       07:00  
  2       04:00     04:10     07:40       08:00  

所以我每站有两列,一列是到达时间,另一列是出发时间。

这是我想将其转换为的格式:

  Train   Station   Arrival   Departure  
 ------- --------- --------- ----------- 
      1   AMS       03:00     03:10      
      1   UTR       06:40     07:00      
      2   AMS       04:00     04:10      
      2   UTR       07:40     08:00      

我挣扎的部分是,列名包含一个我想要作为单独列(到达/离开)的变量和一个我想要作为单独行值(站点)的变量。

一些数据:

d <- structure(list(train = c(1, 2, 1),
                    NYC.A = structure(seq(0.1,0.3,0.1), format = "h:m:s", class = "times"),
                    NYC.D = structure(seq(0.1,0.3,0.1) + .01, format = "h:m:s", class = "times"),
                    BOS.A = structure(seq(0.1,0.3,0.1) + .1, format = "h:m:s", class = "times"),
                    BOS.D = structure(seq(0.1,0.3,0.1) + .11, format = "h:m:s", class = "times")),
               class = "data.frame", .Names = c("train", "NYC.A", "NYC.D", "BOS.A", "BOS.D"), row.names = 1:3)

1 个答案:

答案 0 :(得分:0)

您可以通过以下方式解决此问题:

f <- tidyr::gather(d, train) %>%
  setNames(c('train', 'event', 'time')) %>%
  tidyr::separate(col = 2, into = c("station", "arr.dep"), sep = "[.]") %>%
  reshape2::dcast(formula = train + station ~ arr.dep, value.var = 'time') %>%
  dplyr::mutate(train = factor(train)) %>%
  dplyr::mutate_if(is.numeric, function(x) structure(x, format = 'h:m:s', class = 'times'))

这包括以下步骤:

  1. 使用gather转换为长格式。
  2. 更改列名称(因为gather因某种原因使它们变得非常奇怪)
  3. 使用separate将合并列拆分为两列。 sep参数是一个正则表达式,因此用.括起来使其成为字面值。
  4. 使用dcast,将arr.dep变量重新转换为两列时间数据。
  5. 最后一步搞砸了您的时间数据类型,因此将数字转换回时间。
  6. 最后一个问题是:dcast方法意味着trainstation的每个组合必须仅在ONCE上发生。如果数据包含一列火车的更多行,dcast将开始返回计数,您不希望这样。还有一个简单的解决方案:在开始之前,为数据中的每一行创建一个唯一标识符,这可以保证数据中每个ID只有一个A和一个D行。然后,您可以根据此唯一标识符使用dcast