代码之家  ›  专栏  ›  技术社区  ›  melbez

按R中的第一个字母和数字对多个列进行排序

  •  1
  • melbez  · 技术社区  · 6 年前

    我创建了一个如下所示的数据帧:

    item  mean
    a_b   5
    a_c   2
    a_a   4
    b_d   7
    b_f   3
    b_e   1
    

    我想对它进行排序,以便首先根据它是否以“A”或“B”开头进行排序,然后按平均值进行排序。最终的数据帧应该如下所示:

    item  mean
    a_c   2
    a_a   4
    a_b   5
    b_e   1
    b_f   3
    b_d   7
    

    请注意,项目列没有按字母顺序完全排序。它只按第一个字母排序。

    我尝试过:

    arrange(df, item, mean) 
    

    问题在于,它不仅按“A”和“B”类别排序,而且按整个项目名称排序。

    我愿意使用过滤器将原始数据帧分离为单独的数据帧,然后在这些较小的子集中对平均值进行排序。我不需要一切都保持在同一个数据帧中。但是,我不确定如何使用过滤器只选择以“a_uuu”或“b_uuu”开头的项目的行。

    3 回复  |  直到 6 年前
        1
  •  2
  •   acylam    6 年前

    另一种方法使用 dplyr :

    library(dplyr)
    arrange(df, sub('_.+$', '', item), mean)
    

    另一种选择是使用 str_extract stringr 只从中提取第一个字母 item :

    library(stringr)
    arrange(df, str_extract(item, '^._'), mean)
    

    结果:

      item mean
    1  a_c    2
    2  a_a    4
    3  a_b    5
    4  b_e    1
    5  b_f    3
    6  b_d    7
    

    数据:

    df <- structure(list(item = c("a_b", "a_c", "a_a", "b_d", "b_f", "b_e"
    ), mean = c(5L, 2L, 4L, 7L, 3L, 1L)), .Names = c("item", "mean"
    ), class = "data.frame", row.names = c(NA, -6L))
    

    笔记:

    • sub('_.+$', '', item) 通过创建临时变量 正在删除 _ 从那以后的一切 项目 . _.+$ 匹配文本下划线( γ )后跟任何字符一次或多次( .+ )在字符串的末尾( $ )

    • str_extract(item, '^._') 通过创建临时变量 提取 任何一个字符( . )后跟一个文字下划线( γ )在字符串的开头( ^ )

    • 关于 dplyr::arrange 您可以在函数中创建临时排序变量,而不将其包含在输出中。

        2
  •  1
  •   AntoniosK    6 年前

    哲学是如果你想 arrange 通过某些东西(即这里的子字符串),您必须首先获得它:

    df = read.table(text = "
    item  mean
    a_b   5
    a_c   2
    a_a   4
    b_d   7
    b_f   3
    b_e   1
    ", header=T, stringsAsFactors=F)
    
    library(tidyverse)
    
    df %>%
      separate(item, c("item1","item2"), remove = F) %>% # split items while keeping the original column
      arrange(item1, mean) %>%                           # arrange by what you really want
      select(item, mean)                                 # keep only relevant columns
    
    #   item mean
    # 1  a_c    2
    # 2  a_a    4
    # 3  a_b    5
    # 4  b_e    1
    # 5  b_f    3
    # 6  b_d    7
    

    请注意,有多种方法可以从字符串中选择第一个字母。我刚决定用 separate 在这里。

    如果你有很多物品 _ 您仍然需要提取第一个项目,以便替换第一个项目 γ 使用另一个分隔符(例如 : )把你的专栏分开:

    df = read.table(text = "
    item  mean
    a_b_m   5
    a_c   2
    a_a   4
    b_d_x_q   7
    b_f   3
    b_e   1
    ", header=T, stringsAsFactors=F)
    
    library(tidyverse)
    library(stringr)
    
    df %>%
      mutate(item2 = str_replace(item, "_", ":")) %>%
      separate(item2, c("item1","item2"), remove = F, sep = ":") %>% 
      arrange(item1, mean) %>%                           
      select(item, mean) 
    
    #      item mean
    # 1     a_c    2
    # 2     a_a    4
    # 3   a_b_m    5
    # 4     b_e    1
    # 5     b_f    3
    # 6 b_d_x_q    7
    
        3
  •  0
  •   Rui Barradas    6 年前

    基本的R解决方案是

    inx <- order(substr(df$item, 1, 1), df$mean)
    newdf <- df[inx, ]
    
    newdf
    #  item mean
    #2  a_c    2
    #3  a_a    4
    #1  a_b    5
    #6  b_e    1
    #5  b_f    3
    #4  b_d    7