2015-04-17 4 views
6

я не могу найти способ сделать это ...извлечь разницу («относительное дополнение») между двумя строками в г

raw_string <- "\"+001\", la bonne surprise de M. Jenn M. Ayache http://goo.gl/3EXxy6 via @MYTF1News" 

clean_string <- "+001, la bonne surprise de Jenn Ayache" 

desired_string <- "\"\"M. M. http://goo.gl/3EXxy6 via @MYTF1News" 

Я не уверен, о том, как назвать эту трансформацию. Я бы сказал «разницу» (как в теории множеств, против «союза» и «пересечения»). Лучшее имя может быть «относительным дополнением» (http://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement).

Моя искомая строка имеет только и все символы, отсутствующие в clean_string, в порядке, один раз для каждого появляющегося момента, включая пробелы, знаки препинания и все такое.

Лучшим, что я смог сделать, это не достаточно хорошо:

> a <- paste(Reduce(setdiff, strsplit(c(raw_string, clean_string), split = " ")), collapse = " ") 
> a 
[1] "\"+001\", M. http://goo.gl/3EXxy6 via @MYTF1News" 

ответ

1

Я не знаю, если есть реализованная функция для этого в одном из пакетов обработки строк (я не встречал Это). Это реализация которых (я думаю) работает

raw_string <- "\"+001\", la bonne surprise de M. Jenn M. Ayache http://goo.gl/3EXxy6 via @MYTF1News" 
clean_string <- "+001, la bonne surprise de Jenn Ayache" 
raw <- strsplit(raw_string, "")[[1]] 
clean <- strsplit(clean_string, "")[[1]] 
dif <- vector("list") 
j <- 1 
while(length(clean) > 0) { 
    i <- match(clean[1], raw) 
    if (i > 1) { 
     dif[[j]] <- raw[seq_len(i - 1)] 
     j <- j + 1 
    } 
    clean <- clean[-1] 
    raw <- raw[-seq_len(i)] 
} 
dif[[j]] <- raw 
paste(unlist(dif), collapse = "") 
#[1] "\"\"M. M. http://goo.gl/3EXxy6 via @MYTF1News" 
+0

Спасибо, но я не понимаю, почему он не работает с этими двумя строками: 'raw_string <-«\»Tranquille, 196 досье де détenus trouvés данс ла Рю (по ле а) \» HTTP: //rue89.nouvelobs.com/2014/09/02/tranquille-196-dossiers-detenus-trouves-rue-les-a-254557 через @ Rue89 "и' clean_string <- "Tranquille, 196 досье de détenus trouvés dans la rue (on les a) "' –

+0

Кажется, что это дает '' \ "\" http://rue89.nouvelobs.com/2014/09/02/tranquille-196-dossiers-detenus-trouves-ru e -les-a-254557 via @ Rue89 "' – konvas

+0

Вы правы: я получил ошибку при применении функции к столбцу строк, проблема должна быть в моем внешнем цикле! Я снова проверяю –

3

я хотел бы использовать цикл, тоже:

x <- strsplit(raw_string, "")[[1]] 
y <- strsplit(clean_string, "")[[1]] 

res <- character(length(x)) 

j <- 1 

for(i in seq_along(x)) { 
    if (j > length(y)) { 
    res[i:length(x)] <- x[i:length(x)] 
    break 
    } 
    if (x[i] != y[j]) { 
    res[i] <- x[i] 
    } else { 
    j <- j + 1 
    } 
} 

paste(res, collapse = "") 
#[1] "\"\"M. M. http://goo.gl/3EXxy6 via @MYTF1News" 

Примечания дополнительного пространства по сравнению с ожидаемым результатом. Я думаю, вы просто пропустили это.

Если это слишком медленно, его следует легко реализовать с помощью Rcpp.

+2

Кажется, работает на меня. Что означает «не работает»? – Roland

+0

извините, моя ошибка, проверка снова ... –

+0

Я получаю странный результат при использовании в качестве сырых и чистых строк содержимого столбца data.frame. Я извлекаю содержимое ячейки с этим 'data $ raw_string [17]'. Если я это сделаю, я получаю другой результат, чем если бы я прямо присвоил значение моим строкам. Я открываю новый вопрос, спасибо! –

1

Ниже приводится краткое описание, используя sub, который требует от вас учета символов.

str_relative_complement <- function(raw_string, clean_string){ 
    words <- strsplit(clean_string, "")[[1]] 
    cur_str <- raw_string 
    for(i in words){ 
     cur_str <- sub(ifelse(grepl("[[:punct:]]", i), paste0("\\", i), i), "", cur_str) 
    } 
    return(cur_str) 
} 

raw_string <- '\"+001\", la bonne surprise de M. Jenn M. Ayache http://goo.gl/3EXxy6 via @MYTF1News' 
clean_string <- "+001, la bonne surprise de Jenn Ayache" 

str_relative_complement(raw_string, clean_string) 
[1] "\"\"M. M. http://goo.gl/3EXxy6 via @MYTF1News" 
Смежные вопросы