как найти различия между похожими строками? - PullRequest
1 голос
/ 20 февраля 2020

У меня есть вектор строк (точнее, имен файлов).

pav <- c("Sn_4Khz_3W_45_130_02_30cm_101mm_",
         "Sn_4Khz_4W_45_130_02_30cm_101mm_",
         "Sn_4Khz_4W_50_130_02_30cm_101mm_")

Я ищу простой способ найти разницу между этими строками.

`> char_position_fun(pav) # gives unique character position
[1] 9 12 13 `


`> char_diff_fun(pav) # removes matching components (position and value)
[1] 3_4_5  4_4_5  4_5_0`

Ответы [ 2 ]

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

Вот моя попытка. Я решил разделить все буквы и создать фрейм данных для каждой строки, содержащей информацию о позиции и букве. Затем для каждой позиции я проверял, есть ли одно уникальное письмо или нет. Если ЛОЖЬ, это означает, что не все буквы идентичны. Наконец, установите для фрейма данных логическое условие. Таким образом, вы можете видеть информацию о позиции и букве вместе.

library(tidyverse)

strsplit(mytext, split = "") %>% 
map_dfr(.x = .,
        .f = function(x) enframe(x, name = "position", value = "word"),
        .id = "id") %>% 
group_by(position) %>% 
mutate(check = n_distinct(word) == 1) %>% 
filter(check == FALSE)

  id    position word  check
  <chr>    <int> <chr> <lgl>
1 1            9 3     FALSE
2 1           12 4     FALSE
3 1           13 5     FALSE
4 2            9 4     FALSE
5 2           12 4     FALSE
6 2           13 5     FALSE
7 3            9 4     FALSE
8 3           12 5     FALSE
9 3           13 0     FALSE

Если вы хотите получить результат, как вы описали, вы можете добавить немного больше операции.

strsplit(mytext, split = "") %>% 
map_dfr(.x = .,
        .f = function(x) enframe(x, name = "position", value = "word"),
        .id = "id") %>% 
group_by(position) %>% 
mutate(check = n_distinct(word) == 1) %>% 
filter(check == FALSE) %>% 
group_by(id) %>% 
summarize_at(vars(position:word),
             .funs = list(~paste0(., collapse = "_")))

  id    position word 
  <chr> <chr>    <chr>
1 1     9_12_13  3_4_5
2 2     9_12_13  4_4_5
3 3     9_12_13  4_5_0

ДАННЫЕ

mytext <- c("Sn_4Khz_3W_45_130_02_30cm_101mm_", "Sn_4Khz_4W_45_130_02_30cm_101mm_", 
"Sn_4Khz_4W_50_130_02_30cm_101mm_")
0 голосов
/ 20 февраля 2020

Вот базовое решение R.

Сначала мы можем инвертировать строки из UTF8 в Int, т. Е.

z <- Map(utf8ToInt,v)
  • позиции различий
pos <- unique(unlist(outer(z,z,FUN = Vectorize(function(x,y) which(x!=y)))))

> pos
[1]  9 12 13
  • различные символы:
word <- Map(function(x) paste(intToUtf8(x[p],multiple = T),collapse = "_"),z)

> word
$Sn_4Khz_3W_45_130_02_30cm_101mm_
[1] "3_4_5"

$Sn_4Khz_4W_45_130_02_30cm_101mm_
[1] "4_4_5"

$Sn_4Khz_4W_50_130_02_30cm_101mm_
[1] "4_5_0"

ДАННЫЕ

v <- c("Sn_4Khz_3W_45_130_02_30cm_101mm_", "Sn_4Khz_4W_45_130_02_30cm_101mm_", 
            "Sn_4Khz_4W_50_130_02_30cm_101mm_")
...