简介:这是一个我想问的问题,但最终解决了自己。我希望答案可能对某人有用,所以我将其作为一个已回答的问题留在这里。
我有火车的时间表数据集。我想将其转换为长格式。
这就是我的数据:
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)
答案 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'))
这包括以下步骤:
gather
转换为长格式。gather
因某种原因使它们变得非常奇怪)separate
将合并列拆分为两列。 sep
参数是一个正则表达式,因此用.
括起来使其成为字面值。dcast
,将arr.dep
变量重新转换为两列时间数据。最后一个问题是:dcast
方法意味着train
和station
的每个组合必须仅在ONCE上发生。如果数据包含一列火车的更多行,dcast
将开始返回计数,您不希望这样。还有一个简单的解决方案:在开始之前,为数据中的每一行创建一个唯一标识符,这可以保证数据中每个ID只有一个A
和一个D
行。然后,您可以根据此唯一标识符使用dcast
。