移除存在于列r中其它地方的字符串

8ljdwjyq  于 2023-02-14  发布在  其他
关注(0)|答案(3)|浏览(61)

我有一个包含名称字符串的 Dataframe :

df =data.frame("names" = c("George Orwell; Ayn Rand; Adam Smith", "George Orwell; Rand; Orwell"))
df
                                names
1 George Orwell; Ayn Rand; Adam Smith
2         George Orwell; Rand; Orwell

我想删除所有重复的名字,这样每个列表就只有唯一的名字。在只有姓氏的地方,如果姓氏是唯一的,我想保留它,但如果在同一个字符串中有一个完整的名字,我想删除它。所以上面df的结果是:

names
1 George Orwell; Ayn Rand; Adam Smith
2                 George Orwell; Rand

我只能保留唯一值:

sapply(strsplit(df$names, ";\\s*"), function(z) paste(unique(z), collapse = "; "))
[1] "George Orwell; Ayn Rand; Adam Smith" "George Orwell; Rand; Orwell"

但这会使“Orwell”保留在df$names[2]中。

x6yk4ghg

x6yk4ghg1#

您已接近,我们可以gsub删除除姓氏以外的所有内容,并且paste仅包含!duplicated标记的部分。也适用于中间名(但可能无法处理不带连字符的两部分姓氏)。

strsplit(x, ';\\s+') |> sapply(\(.) paste(.[!duplicated(gsub('.+\\s', '', .))], collapse='; '))
# [1] "George Orwell; Ayn Rand; Adam Smith" "George Orwell; Rand"                
# [3] "Michael J Fox; Rand"
  • 数据:*
x <- c("George Orwell; Ayn Rand; Adam Smith", "George Orwell; Rand; Orwell", 
"Michael J Fox; Rand; Fox")
2q5ifsrm

2q5ifsrm2#

尽管这不是有效的答案而是替代方法

df %>% mutate(row=row_number()) %>% separate_rows(names, sep = ';', convert = T) %>% 
  mutate(names=trimws(names)) %>% 
  separate(names, c('first','last'), sep='\\s', remove = F, fill = 'left') %>% 
  group_by(row,last) %>% slice_head(n=1) %>% ungroup() %>% 
  group_by(row) %>% 
  mutate(names=paste0(names, collapse = ';')) %>% slice_head(n=1) %>% ungroup %>% 
  select(names)

创建于2023年2月12日,使用reprex v2.0.2

# A tibble: 2 × 1
  names                            
  <chr>                            
1 George Orwell;Ayn Rand;Adam Smith
2 George Orwell;Rand
igetnqfo

igetnqfo3#

可能的解决方案:
此脚本将按姓氏识别重复项,但在每种情况下检索较长的名称。

df <- data.frame("names" = c("George Orwell; Ayn Rand; Adam Smith", "George Orwell; Rand; Orwell"))

fullnames <- strsplit(df$names, "; +")
lastnames <- lapply(strsplit(df$names, "; +"), \(x) gsub(".* ([^ ]+)", "\\1", x))
elements <- lapply(lastnames, \(x)as.integer(factor(x)))

df$names2 <- sapply(FUN = paste, collapse = "; ",
  mapply(fullnames, elements, FUN = \(name, elem)  
       sapply(unique(elem), \(i) name[elem=i][which.max(nchar(name[elem==i]))])))

df
#>                                 names                              names2
#> 1 George Orwell; Ayn Rand; Adam Smith George Orwell; Ayn Rand; Adam Smith
#> 2         George Orwell; Rand; Orwell                 George Orwell; Rand

相关问题