使用开始和结束列将数据重新排序为连续序列

时间:2019-06-17 22:10:31

标签: r sorting dataframe sequence

我有一个数据框,其中每一行都有一个开始和结束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

2 个答案:

答案 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)

enter image description here

答案 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)))), ]