【问题标题】:ordering data frame based on factor levels indices in r根据 r 中的因子水平指数对数据框进行排序
【发布时间】:2020-06-16 23:31:55
【问题描述】:

我有一个如下所示的数据框:

df <- data.frame(Name = c("BB", "AA", "AA", "BB", "DD", "AA", "DD", "DD", "CC"), 
             string = c("a11", "a120", "a120", "a8", "a45", "a11", "a140", "a8", "a45") ,
             value = rnorm(9, mean = 0, 1))

Name  string   value

 BB    a11  0.5912728
 AA   a120  0.5885065
 AA   a120 -0.5287264
 BB     a8  0.6932831
 DD    a45 -0.2892612
 AA    a11  1.0441365
 DD   a140 -0.5091612
 DD     a8 -0.3358695
 CC    a45  0.5598616

我想重新排序 df,使其根据数字部分 pf 字符串列进行排序。

我正在尝试以下命令:

string <- unique(as.character(df$string))
sorted.ind <- sort(as.numeric(gsub('a', '', string)), index.return = T)$ix
df$string <- factor(df$string, levels = string[sorted.ind])  

但它也不会重新排序表。

这是我想要的输出:

Name  string  value

BB     a8  0.6932831
DD     a8 -0.3358695
BB    a11  0.5912728
AA    a11  1.0441365
DD    a45 -0.2892612
CC    a45  0.5598616
AA   a120  0.5885065
AA   a120 -0.5287264
DD   a140 -0.5091612

有人知道如何修复我的代码吗?

谢谢

【问题讨论】:

    标签: r dataframe dplyr tidyr


    【解决方案1】:

    您可以使用dplyr,如下所示。这是另一个答案的变体,不使用stringr

    library(dplyr)
    df %>%
       arrange(as.numeric(gsub("\\D+", "", string)))
    
    ##   Name string       value
    ## 1   BB     a8  0.35120965
    ## 2   DD     a8  0.54526648
    ## 3   BB    a11 -0.90101120
    ## 4   AA    a11  1.65637910
    ## 5   DD    a45  0.42240082
    ## 6   CC    a45 -0.30438594
    ## 7   AA   a120 -0.05781699
    ## 8   AA   a120 -1.83615123
    ## 9   DD   a140 -1.82698618
    
    

    除了string之外,您还可以通过Name进一步排序。

    so.df %>%
      arrange(
          as.numeric(gsub("\\D+", "", string)),
          Name
      )
    ##   Name string       value
    ## 1   BB     a8  0.35120965
    ## 2   DD     a8  0.54526648
    ## 3   AA    a11  1.65637910
    ## 4   BB    a11 -0.90101120
    ## 5   CC    a45 -0.30438594
    ## 6   DD    a45  0.42240082
    ## 7   AA   a120 -0.05781699
    ## 8   AA   a120 -1.83615123
    ## 9   DD   a140 -1.82698618
    

    【讨论】:

      【解决方案2】:

      你可以去掉非数字并像这样排列:

      library(stringr)
      library(dplyr)
      
      df %>%
        arrange(as.numeric(str_remove(string, "\\D+")))
      
        Name string       value
      4   BB     a8  1.74351093
      8   DD     a8  0.41802240
      1   BB    a11  0.61559079
      6   AA    a11  0.63900177
      5   DD    a45 -1.87046411
      9   CC    a45 -0.44398027
      2   AA   a120 -0.84459958
      3   AA   a120  0.01800482
      7   DD   a140 -0.88140002
      

      【讨论】:

      • 是的,如果第一个字母是“a”,则此方法有效。但是在我的真实数据中,我有不同的字母,我想忽略字母,然后仅根据数字部分对数据进行排序。你有什么想法吗?
      • 你能试试这个数据框吗? df
      • 字母(即a120、b120、c120)是否有优先顺序?
      【解决方案3】:

      你可以使用gtools::mixedorder

      df[gtools::mixedorder(df$string), ]
      
      #  Name string      value
      #4   BB     a8 -0.9128301
      #8   DD     a8 -0.5483317
      #1   BB    a11 -1.2260433
      #6   AA    a11 -0.4713301
      #5   DD    a45 -0.3376227
      #9   CC    a45 -1.0200505
      #2   AA   a120 -0.2612332
      #3   AA   a120 -1.1606446
      #7   DD   a140 -0.7210719
      

      此外,如果string 中有其他字符并且您只对数字感兴趣,则可以使用parse_number 提取数字并使用order 提取它。

      df[order(readr::parse_number(df$string)),]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 2022-08-20
        • 1970-01-01
        • 2011-12-08
        相关资源
        最近更新 更多