R — Объединить уникальные значения из двух списков с помощью stringr::str_split

#r #stringr #strsplit

#r #stringr #strsplit

Вопрос:

У меня есть функция, которая при задании списка строк должна возвращать вектор всех уникальных строк размером N.

 get_unique <- function (input_list, size = 3) {
   output = c()

   for (input in input_list) {
    current = stringr::str_replace(input, "[-_\s]", "")
    current = trimws(gsub(paste0("(.{",size,"})"), "\1 ", current))
    parts = stringr::str_split(current, "\s", simplify = TRUE)[1,]
    output = union(output, parts)
   }

   return(output)
}
 

Ожидание, которое я имею, было бы:

 get_unique(c("ABC", "ABCDEF", "GHIDEF"))

[1] "ABC" "DEF" "GHI"
 

Но то, что я получаю, это:

 get_unique(c("ABC", "ABCDEF", "GHIDEF"))

[[1]]
[1] "ABC"

[[2]]
[1] "DEF"

[[3]]
[1] "GHI"
 

Я довольно новичок в R, поэтому мне трудно понять, где я ошибся.

Ответ №1:

Мы можем использовать unlist в конце

 get_unique <- function (input_list, size = 3) {
  output = c()

  for (input in input_list) {
     current = stringr::str_replace(input, "[-_\s]", "")
     current = trimws(gsub(paste0("(.{",size,"})"), "\1 ", current))
    parts = stringr::str_split(current, "\s", simplify = TRUE)[1,]
    output = union(output, parts)
  }

  return(unlist(output))
 }

get_unique(c("ABC", "ABCDEF", "GHIDEF"))
#[1] "ABC" "DEF" "GHI"
 

Мы также могли бы сделать это в одной строке с помощью регулярного выражения для разделения на каждые 3 символа

 unique(unlist(strsplit(v1, "(?<=...)", perl = TRUE)))
#[1] "ABC" "DEF" "GHI"
 

данные

 v1 <- c("ABC", "ABCDEF", "GHIDEF")
 

Комментарии:

1. @akrun не могли бы вы кратко объяснить, что в этом происходит regex ?

Ответ №2:

полное baseR решение, используя substr :

 get_unique <- function(v) unique(unlist(sapply(v, function(x) sapply(1:(nchar(x)/3), function(y) substr(x, 3*(y-1) 1, 3*y) ))))

get_unique(v1)
[1] "ABC" "DEF" "GHI"
 
  • substr(x, 3*(y-1) 1, 3*y) возьмите 3-символьные подстроки из x.