我想按之前行中的值对数据框进行排序。这就是为什么 我有两列“startpoint”和“endpoint” 现在我想对行进行排序,以便每个具有特定“端点”的行后跟“startpoint”中具有相同值的行。
例如:
+------------+-----------+
| Startpoint | Endpoint |
+------------+-----------+
| Berlin | Munich |
| Munich | Paris |
| Paris | Barcelona |
| Barcelona | Rom |
+------------+-----------+
答案 0 :(得分:0)
这是一个非常复杂的第一个解决方案,我欢迎尝试改进,因为我不太了解排序算法。我认为这也不适用于任何大型桌子,因为permutations
的尺寸增加得太快(毕竟它是因素)。
我首先制作一个带有一些值列的重新排序版本,因为这可能是我们必须重新排列行的原因。首先获取所有潜在行顺序的列表。然后检查行以查看下一个start
是否等于当前end
,如果是,则将这些行保持在一起。过滤掉那些不具有这些行的行顺序,然后将表随机混洗到剩余的行顺序之一。当只剩下一个选项时停止。
这清楚地假设有一个独特的解决方案(实际上至少有两个解决方案,因为你可以反转这个顺序并满足条件,但是在一个随机选择的时候会随机选择)。
library(tidyverse)
library(arrangements)
set.seed(100)
tbl <- tibble(
start = c("Berlin", "Munich", "Paris", "Barcelona"),
end = c("Munich", "Paris", "Barcelona", "Rome"),
val = rnorm(4)
) %>%
slice(sample(1:nrow(.), nrow(.))) %>%
rowid_to_column()
tbl
#> # A tibble: 4 x 4
#> rowid start end val
#> <int> <chr> <chr> <dbl>
#> 1 1 Paris Barcelona -0.0789
#> 2 2 Berlin Munich -0.502
#> 3 3 Munich Paris 0.132
#> 4 4 Barcelona Rome 0.887
row_orders <- permutations(nrow(tbl)) %>%
as_tibble() %>%
unite(order, remove = FALSE) %>%
nest(-order) %>%
mutate(data = map(data, as.integer))
sample_orders <- row_orders
sample_tbl <- tbl
while (nrow(sample_orders) > 1) {
keep_together <- sample_tbl %>%
mutate(
nrc = lead(start) == end,
nrc = replace_na(nrc, FALSE),
cumsum = cumsum(lag(nrc, default = FALSE) == FALSE)
) %>%
group_by(cumsum) %>%
summarise(row_groups = str_c(rowid, collapse = "_")) %>%
filter(str_length(row_groups) > 1) %>%
`[[`("row_groups")
sample_orders <- sample_orders %>%
filter(str_detect(order, keep_together))
sample_tbl <- tbl %>%
slice(sample_orders$data[[sample(1:nrow(sample_tbl), 1)]])
}
#> Error in slice_impl(.data, dots): Evaluation error: subscript out of bounds.
print(sample_tbl)
#> # A tibble: 4 x 4
#> rowid start end val
#> <int> <chr> <chr> <dbl>
#> 1 2 Berlin Munich -0.502
#> 2 3 Munich Paris 0.132
#> 3 1 Paris Barcelona -0.0789
#> 4 4 Barcelona Rome 0.887
由reprex package(v0.2.0)创建于2018-04-19。
答案 1 :(得分:0)
对于不遵循发布指南的操作答案,我有点矛盾,但我发现这是一个有趣的解决难题。
如果没有冲突,例如有多个航班(我认为他们是航班)与同一个出发地(或目的地),或者有一系列“往返”,在这种情况下你会跑进入无限循环,这是一个(有点令人惊讶的简单)解决方案。
flights <- read.table(sep = ",", stringsAsFactors = FALSE, header = TRUE, text = "
dep,arr
Montreal,Washington
Berlin,Munich
Miami,Paris
Munich,New York
Barcelona,Rome
New York,Montreal
Washington,Miami
Paris,Barcelona
")
cont <- TRUE
while (cont) {
# move down a flight for which the dep is an arr further down
for (i in 1:(nrow(flights)-1)) {
ind <- which(flights$arr == flights$dep[i])
if (length(ind) == 0) next
if (ind > i) {
flights <- flights[c(seq_len(i-1),
(i+1):ind,
i,
seq(from = ind + 1,
length.out = nrow(flights) - ind)),]
break
}
cont <- FALSE
}
}
> flights
dep arr
2 Berlin Munich
4 Munich New York
6 New York Montreal
1 Montreal Washington
7 Washington Miami
3 Miami Paris
8 Paris Barcelona
5 Barcelona Rome