代码之家  ›  专栏  ›  技术社区  ›  A. Stam

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

r
  •  0
  • A. Stam  · 技术社区  · 8 年前

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


    我有一个火车时刻表数据集。我想把它转换成长格式。

    以下是我的数据:

      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 回复  |  直到 8 年前
        1
  •  0
  •   A. Stam    8 年前

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

    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. 更改列名(因为 聚集 出于某种原因,这让他们非常奇怪)
    3. 使用将组合柱拆分为两个 separate . 这个 sep 参数是正则表达式,因此将 . 用方括号表示文字。
    4. 使用 dcast ,转动 arr.dep 变量返回到两列时间数据中。
    5. 最后一步搞乱了时间数据类型,所以请将数字转换回时间。

    最后一个陷阱是 dcast 方法意味着 train 和 station 只能发生一次。如果数据包含一列的更多行, dcast 将开始返回计数,您不希望这样。还有一个简单的解决方案:在开始之前,为数据中的每一行创建一个唯一的标识符,这可以保证有一个唯一的标识符 A 还有一个 D 数据中每个ID的行数。然后您可以使用 dcast 基于此唯一标识符。