一种更优雅的方法来删除字符串元素中的重名(短语)

A more elegant way to remove duplicated names (phrases) in the elements of a character string


我在数据框中有一个组织名称向量。其中一些很好,其他的名称在同一元素中重复了两次。此外,当重复该名称时,没有分隔符 space,因此该名称具有驼峰式外观。

例如(为一般数据框引用添加的 id 列):
id 组织
1 个阿尔法连
2 Bravo InstituteBravo Institute
3 查理集团
4 Delta IncorporatedDelta Incorporated

但它应该看起来像:
id 组织
1 个阿尔法连
2 布拉沃学院
3 查理集团
4 达美公司

我有一个解决方案可以得到我需要的结果 -- 下面是可重现的示例代码。不过,显得有点冗长,不太优雅。

对于相同的结果,有没有人有更好的方法?

额外问题:如果组织包含 'types',例如 Alpha Company, LLC,那么我修复驼峰式命名的 gsub() 行也无法正常工作。关于如何调整驼峰式修复以解决“, LLC”并仍然与解决方案的其余部分一起工作的任何建议?

提前致谢! (感谢 OP 和那些在 previous SO post about splitting camelCase strings in R 上提供帮助的人)

# packages
library(stringr)
# toy data
df <- data.frame(id=1:4, org=c("Alpha Company", "Bravo InstituteBravo Institute", "Charlie Group", "Delta IncorporatedDelta Incorporated"))
# split up & clean camelCase words
df$org_fix <- gsub("([A-Z])", " \1", df$org)
df$org_fix <- str_trim(str_squish(df$org_fix))
# temp vector with half the org names
df$org_half <- word(df$org_fix, start=1, end=(sapply(strsplit(df$org_fix, " "), length)/2)) # stringr::word
# double the temp vector
df$org_dbl <- paste(df$org_half, df$org_half)
# flag TRUE for orgs that contain duplicates in name
df$org_dup <- df$org_fix == df$org_dbl
# corrected the org names
df$org_fix <- ifelse(df$org_dup, df$org_half, df$org_fix)
# drop excess columns
df <- df[,c("id", "org_fix")]

# toy data for the bonus question
df2 <- data.frame(id=1:4, org=c("Alpha Company, LLC", "Bravo InstituteBravo Institute", "Charlie Group", "Delta IncorporatedDelta Incorporated"))

如果所有单个单词都以大写字母开头(后面没有其他大写字母),那么您可以使用它来拆分。只保留独特的元素,粘贴+折叠。也适用于额外的 LCC 选项

org <- c("Alpha CompanyCompany , LLC", "Bravo InstituteBravo Institute", "Charlie Group", "Delta IncorporatedDelta Incorporated")

sapply(
  lapply(
    strsplit(gsub("[^A-Za-z0-9]", "", org), 
             "(?<=[^A-Z])(?=[A-Z])", 
             perl = TRUE),
    unique), 
  paste0, collapse = " ")

[1] "Alpha Company LLC"  "Bravo Institute"    "Charlie Group"      "Delta Incorporated"

您可以在下面的这一行中使用正则表达式:

my_df$org <- str_extract(string = my_df$org, pattern = "([A-Z][a-z]+ [A-Z][a-z]+){1}")

另一种方法是将字符串的前半部分与字符串的后半部分进行比较。如果相等,则选择上半部分。如果公司名称中存在数字、下划线或任何其他字符,它也适用。

org <- c("Alpha Company", "Bravo InstituteBravo Institute", "Charlie Group", "Delta IncorporatedDelta Incorporated", "WD40WD40", "3M3M")

ifelse(substring(org, 1, nchar(org) / 2) == substring(org, nchar(org) / 2 + 1, nchar(org)), substring(org, 1, nchar(org) / 2), org)

# [1] "Alpha Company" "Bravo Institute" "Charlie Group" "Delta Incorporated" "WD40" "3M"