【问题标题】:Reorder data with start and end columns into contiguous sequence将具有开始列和结束列的数据重新排序为连续序列
【发布时间】:2019-10-31 12:43:22
【问题描述】:

我有一个数据框,其中每一行都有一个开始和一个结束 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 应该“连接”以形成一个连续的链。一个简单的视觉表示:

120 -> 130                       
       130 -> 150                
              150 -> 100
                     100 -> 180

所需的重新排序数据:

#   start_id end_id
# 4      120    130
# 1      130    150
# 3      150    100
# 2      100    180

【问题讨论】:

    标签: r sorting dataframe sequence


    【解决方案1】:

    将您的数据框转换为图表。使用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)
    

    【讨论】:

      【解决方案2】:

      这是使用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,根据您的评论,您可以使用readr 中的parse_number(),它是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)))), ]
      

      【讨论】:

      • 谢谢!如果 id 在数值上不是递增的,只是随机的,但需要连接点怎么办
      • @santoku 抱歉,我没听明白?这不是你需要的吗?
      • 所以如果df是df= data.frame(start_id=c("B130","100","150A","120",'90'), end_id=c("150A ","180","100","B130",'20')) 如何解析出 b130-150a-100-180 是连续性的?
      • 使用parse_number() from readr() 这是tidyverse的一部分 - df[order(apply(df, 1, function(x) max(parse_number(x)))), ]
      • @santoku 我认为 Henrik 的答案可能正是您想要的。请检查一下。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 2022-06-21
      • 2023-03-17
      • 1970-01-01
      • 2017-04-13
      相关资源
      最近更新 更多