在R中按字母顺序排序全名

5
通常需要将全名(和头衔等)分成多个列,以按“姓氏”字母顺序排序行。当单个列包含完整姓名时,我从未遇到过在SQL中实现这一点的简单方法。
但是,我知道R有数千个库 - 尽管我还没有遇到任何可以在不将名字,姓氏和头衔分别放入自己的列中就能做到这一点的示例 - 但我想看看是否有一种稍微更有效的方法来处理这种情况。
我正在使用具有单个列的完整名称的数据集。例如:
     Names
1    Robert Johnson                                  
2    Billy Joel                               
3    Donald Fagen                          
4    Trent Reznor                                
5    Wolfgang Mozart

我需要按字母顺序对它们进行排序,而不创建其他列。到目前为止,我不确定这是否可能,但我找到了一个相对轻松的解决方法。幸运的是,每个名称都遵循“名字”(空格)“姓氏”的约定。因此,我可以使用tidyr库中的separate()函数轻松地隔离出姓氏:

library(tidyverse)
library(magrittr)

# Separate into "first name" and "last name" columns
data %<>% separate(Names, c('first_name', 'last_name'), sep = ' ')

    first_name       last_name
1     Robert           Johnson                                    
2     Billy            Joel                                    
3     Donald           Fagen                                    
4     Trent            Reznor
5     Wolfgang         Mozart

接下来,我可以使用arrange()函数按字母顺序对新的“last name”列进行排序并立即使用unite()函数重建原始列:

# Arrange rows alphabetically by last name
data %<>% arrange(last_name)

# Rebuild original column and dissolve temporary 2nd column
data %>% unite(Names, first_name:last_name, sep=' ')

这样可以成功重建原始表,并通过姓氏字母顺序排列“Names”列。是否有另一种方法可以实现此操作而无需甚至暂时创建第二个“姓氏”列?接受任何额外的R库。谢谢!

2个回答

4
在这里要使用的`tidyverse`函数是来自`stringr`包的`str_extract`。相比于`gsub`或`str_replace`,这个函数更简单,因为你不需要用""替换字符串的捕获部分。
library(tidyverse)
library(stringr)

data %>%
    arrange(str_extract(Names,'\\s.*$'))

是的,非常有效,将代码从3行减少到1行。谢谢! - RVD

3
你可以使用 `dplyr` 和一个简单的 `gsub` 调用来做到这一点。
library(dplyr)
data %>%
  arrange(gsub(".*\\s", "", Names))

            Names
1    Donald Fagen
2      Billy Joel
3  Robert Johnson
4 Wolfgang Mozart
5    Trent Reznor

好的解决方案。在我的端上工作正常。谢谢! - RVD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接