我有一个包含名称和姓氏列的数据框。我需要删除所有的名字,只保留姓氏,在第一列中,也就是说,在第一列的每个单元格中删除文本的第一部分。
Sociologist Referencia
1 Peter Abell Peter Abell
2 Mark Abrams Mark Abrams
3 Janet Abu-Lughod Janet Abu-Lughod
4 Jane Addams Jane Addams
5 Theodor W. Adorno Theodor W. Adorno
6 Richard Alba Richard Alba
我尝试了一个类似问题的代码,但是它消除了我需要的姓氏,而不是名字。代码如下:
Sociologos_df$word<- sub("([A-Za-z]+).*", "\\1", Sociologos_df$word)
那么,如何删除列中字符串的第一部分?
答案 0 :(得分:0)
如果您将sub("([A-Za-z]+).*", "\\1", df$word)
用作名字,则可以使用类似物作为姓氏:
sub(".*\\s([A-Za-z]+)$", "\\1", dat$Sociologist)
# [1] "Abell" "Abrams" "Lughod" "Addams" "Adorno" "Alba"
不过请注意,我们正在将Abu-
砍掉,在这种情况下,您可能想扩展字母的逻辑。
sub(".*\\s([-A-Za-z]+)$", "\\1", dat$Sociologist)
# [1] "Abell" "Abrams" "Abu-Lughod" "Addams" "Adorno" "Alba"
请注意,-
中的前导[-A-Za-z]
表示文字破折号,其他任何破折号均表示字符范围(即A-Z
表示*“从A
到{{ 1}},按字典顺序)。
或者,如果您想更加自由一些,则可以使用Z
(大写“ S”)表示“任何非空白”:
\\S
这会产生与前一个相同的输出,但是它可能允许其他一些字符,例如单引号(例如sub(".*\\s(\\S+)$", "\\1", dat$Sociologist)
),也许还有其他我在这里考虑不大的字符。虽然我怀疑“非空白”逻辑可以很好地处理带重音符号和不同姓氏的名称,但“范·怀尔德”之类的名称将无法正确识别(假设您也希望在其中输入“ van”)。
“ Jr”,“ Sr”,“ III”,“ IV”等问题同样存在。有许多模式可以很好地检测所有这些模式(https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s18.html),尽管通常可能是最好不要尝试将它们全部放在一个模式正则表达式中(例如,先查找“ III”,“ IV”,先捕获并删除,然后再尝试姓氏)。
答案 1 :(得分:0)
不必过多地使用正则表达式并保持简单,我们可以使用word
中的stringr
提取每个名称中的最后一个单词,假设这将是姓氏。
stringr::word(df$Sociologist, -1)
#[1] "Abell" "Abrams" "Abu-Lughod" "Addams" "Adorno" "Alba"
这可能不是一个通用的解决方案,但应适用于大多数情况。
数据
df <- structure(list(Sociologist = c("Peter Abell", "Mark Abrams",
"Janet Abu-Lughod", "Jane Addams", "Theodor W. Adorno", "Richard Alba"
)), class = "data.frame", row.names = c(NA, -6L))