сокращение строки, создающее дубликаты - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь использовать abbreviate, чтобы придумать короткие уникальные сокращения, но они возвращают некоторые неожиданные значения. Если я запускаю:

abbreviate(c('moscowcity', 'ms'), minlength = 2)
moscowcity         ms 
    "msc"       "ms"

, он возвращает «mscw» вместо более простого двухбуквенного сокращения, такого как «mo» или «m c» или «mt» или «my»

Если я изменяю на strict = TRUE, он возвращает дубликаты.

Есть ли способ получить как двухбуквенные сокращения, которые также являются уникальными?

Ответы [ 5 ]

1 голос
/ 20 февраля 2020

Прочитав ответы, похоже, что abbreviate не было создано для того, что я хотел Принимая предложение @ akrun, я написал функцию-обертку для создания уникальных сокращений.

Улучшения приветствуются !!

btrAbbreviate = function(x, maxlen) {


  x = tolower(x)

  res = abbreviate(x, minlength = maxlen, strict = TRUE)
  dups = res[duplicated(res)]
  dupsChk = length(dups)

  while (dupsChk != 0) {
    firstChar = stringr::str_sub(names(dups), 1, 1)

    shfl = stringi::stri_rand_shuffle(substring(names(dups), 2))
    shfl = paste0(firstChar, shfl)

    out = stringr::str_sub(shfl, 1, 2)
    names(out) = names(dups)

    res[names(out)] = out

    dups = res[duplicated(res)]
    dupsChk = length(dups)
  }

  return(res)
}

x = state.name
btrAbbreviate(x, maxlen = 2)
1 голос
/ 20 февраля 2020

Из документации:

Используемый по умолчанию алгоритм (method = "left.kept") аналогичен алгоритму S. Для отдельной строки он работает следующим образом. Первые пробелы на концах строки удаляются. Затем (при необходимости) любые другие пробелы удаляются. Затем удаляются гласные в нижнем регистре, а затем согласные в нижнем регистре.

Другими словами, алгоритм начинается с удаления гласных (таким образом, исключая mo), затем согласных, останавливаясь после создания дубликата. Чтобы добиться того, что вы предлагаете, что очень сложно (загляните в историю сокращений названий почтовых штатов США!), Вам нужно создать собственный алгоритм.

1 голос
/ 20 февраля 2020

Я думаю, что ответ на ваш вопрос

Есть ли способ получить как двухбуквенные сокращения, которые также являются уникальными?

: Нет, по крайней мере не с базой R abbreviate

С ?abbreviate (выделено мое) **:

Используемый по умолчанию алгоритм (method = "left.kept") аналогично S. Для одной строки это работает следующим образом. Первые пробелы на концах строки удаляются. Затем (при необходимости) любые другие пробелы удаляются. Затем удаляются гласные в нижнем регистре, а затем согласные в нижнем регистре. Наконец, если сокращение по-прежнему длиннее, чем длина буквы верхнего регистра и символы удаляются.

Символы всегда удаляются с конца строки сначала . Если элемент names.arg содержит более одного слова (слова разделены пробелами), то по крайней мере одна буква от каждого слова будет сохранена.

Насколько я понимаю, это означает, что вы бы never получить строку типа mc из moscowcity, поскольку c будет удалено, когда алгоритм попытается ms (который затем помечается как не уникальный и используется последнее уникальное значение -> msc

Редактировать:

Но : из-за «правила нескольких слов»

abbreviate(c("moscow city", "ms"), minlength = 2)

Возвращает:

moscow city          ms 
       "mc"        "ms" 
1 голос
/ 20 февраля 2020

Если мы изменим minlength и добавим make.unique, это предотвратит дубликаты

make.unique(abbreviate(c('moscowcity', 'ms'), minlength = 2, strict = TRUE))
#[1] "ms"   "ms.1"

Здесь abbreviate применяется к каждому из элементов в отдельности и не выполняется любые перекрестные проверки, выделено ли ранее то же сокращение

0 голосов
/ 20 февраля 2020

minlength должно быть целым числом, а не логическим. minlength по умолчанию равно 4, и вы установили его на TRUE. Таким образом, minlength говорит, чтобы он всегда имел как минимум 4 символа. Вместо этого вам нужно было бы сделать minlength = 2.

(редактировать: исходный вопрос имел minlength = TRUE, но был изменен)

https://stat.ethz.ch/R-manual/R-devel/library/base/html/abbreviate.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...