我有一个数据框,其中每一行都有一个开始和结束ID:
df <- data.frame(start_id = c("130", "100", "150", "120"),
end_id = c("150", "180", "100", "130"))
# start_id end_id
# 1 130 150
# 2 100 180
# 3 150 100
# 4 120 130
我想对数据进行排序,以使一行中的“ end_id”成为下一行的“ start_id”;起始ID和结束ID应该“连接”以形成连续的链。一个简单的视觉表示:
120 -> 130
130 -> 150
150 -> 100
100 -> 180
所需的重新排序数据:
# start_id end_id
# 4 120 130
# 1 130 150
# 3 150 100
# 2 100 180
答案 0 :(得分:2)
将数据框转换为图形。使用get_diameter
获取最长路径的顶点索引。使用索引来订购原始数据。
library(igraph)
g <- graph_from_data_frame(df)
df[head(get_diameter(g), -1), ]
# start_id end_id
# 4 120 130
# 1 130 150
# 3 150 100
# 2 100 180
或使用一个简单的循环:
# create a vector of row indices
# get the first start ID, pre-allocate the remaining indices with NA
ix <- c(which(!df$start_id %in% df$end_id), rep(NA, nrow(df) - 1))
# for each row, check if end ID in one row matches start ID in the next row
for(i in 2:nrow(df)){
ix[i] <- match(df$end_id[ix[i - 1]], df$start_id)
}
# reorder data
df[ix, ]
get_diameter(g)
# + 5/5 vertices, named, from 8e3b983:
# [1] 120 130 150 100 180
plot(g)
答案 1 :(得分:0)
这是使用dplyr
的一种方法-
df %>%
arrange(apply(., 1, max))
start_id end_id
1 120 130
2 130 150
3 150 100
4 100 180
在基数R中-
df[order(apply(df, 1, max)), ]
start_id end_id
4 120 130
1 130 150
3 150 100
2 100 180
对于注释中的字母数字ids
,您可以使用parse_number()
中readr
中的tidyverse
-
df %>%
arrange(apply(df, 1, function(x) max(parse_number(x))))
# in base R
df[order(apply(df, 1, function(x) max(parse_number(x)))), ]