Search code examples
rstringtext-miningtm

Remove specific words with specific punctuation in R


I'm working on a corpus in R that contains interrogatories in Russian.

In the beginning of each question there is the names of the person speaking written.

By example:

President. - Are you Nikolaj Khvostov?

For an analysis of these interrogatories I would like to remove these names when they come at the beginning of the line (ie, when they are used to identify the speaker), but not when they come in the middle of the text (ie, when the speaker actually says that name). So that there is a specific punctuation which follows.

I tried the following code:

corpus3 <- tm_map(corpus2, removeWords, c("Председатель. —", "Хвостов. -"))

or

corpus3 <- tm_map(corpus2, removeWords, c("President. —", "Khvostov. -"))

But nothing is removed and if I try:

corpus3 <- tm_map(corpus2, removeWords, c("President", "Khvostov"))

All the terms President and Khvostov are removed. But I need to use these names when they're used by during the intervention.

What I mean is that by example:

Input strings:

President. - Are you Nikolaj Khvostov?

Khvostov. - Yes Mr. President.

Desired output:

Are You Nikolaj Khvostov?

Yes Mr. President.

Undesired output generated by the third code block:

Are you Nikolaj?

Yes Mr..

There an example of my data:

It would be easy to do it in word, but I actually have more than 5 000 pages of interrogatory I would like to study. Word is not able to open the document without crashing my computer. That's why I hoped a code would match to help me.

My data is added in R as a Large VCorpus

Председатель. — Алексей Николаевич, вы уже были допрошены один раз 15 марта — не правда ли?

Хвостов. — Да.

Председатель. — Вам известно, что вы в заседании Чрезвычайной Следственной Комиссии?

Хвостов. — Да.

Председатель. — Я просил бы вас, не стесняясь рамками допроса, который с вас снят, рассказать нам все, что вам известно и как члену Государственной Думы и по должности министра внутренних дел, — о действиях бывших министров и прочих высших должностных лиц, расследованием действий которых мы заняты. Нас интересует, конечно, и та тема, которую вы задели при показании, данном вами г. Коровиченко, т.-е. тема о тех кружках, которые стояли рядом с правительством или, быть может, позади его и оказывали известное влияние. Эта тема подлежит углублению… В частности, мы просим вас остановиться на следующем: в своей деятельности министра внутренних дел испытывали ли вы, и в какой мере, и при каких обстоятельствах, — давление этих кружков, о которых вы уже давали показание? Вот канва… Благоволите начать.

Хвостов. — Я должен доложить, что вполне подтверждаю все, уже данное мною в показании. В сущности, это показание я считаю своей обязанностью дать, при чем оно не касается дел должностных и вверенных мне по должности министра внутренних дел, а лишь того, что случалось узнавать по этому поводу и что не входило непосредственно в задачу министра внутренних дел…

Председатель. — Я не понял вашу мысль… У нас не может быть здесь никаких тайн: вы не только в праве, но вы обязаны показать нам абсолютно все то, что вы знаете.

Хвостов. — Кроме тех обязанностей, которые на меня возлагались по должности, я руководствовался долгом русского человека, потому что вопрос касался больного для меня места — я разумею вопрос о шпионаже…

Председатель. — Не расскажете ли вы в такой последовательности: при каких обстоятельствах вы были назначены министром внутренних дел? Это — сперва… [3]

Хвостов. — Может быть, вы мне разрешите взять более глубоко? Вы изволили сказать, что я должен показать то, что мне известно было раньше в качестве члена Государственной Думы… Уже издавна, в качестве члена Государственной Думы, я обратил внимание на немецкое влияние, которое, мне казалось, имелось в правительстве. Я занялся…

Председатель. — Вы когда обратили на это внимание?

Хвостов. — Еще членом Государственной Думы, почти в самом начале прибытия моего в Петроград — в 1912 году… До этого для меня, как служившего в провинции, те или другие влияния на петроградские сферы должны были оставаться в стороне… Единственный раз, когда мне пришлось встретиться с Распутиным, — это было в Нижнем Новгороде, когда я был губернатором. Ко мне приехал Распутин, мне в то время мало известный, о котором я слышал в виде толков, доходивших до провинции. Он предложил мне место министра внутренних дел. Было это, насколько я помню, — за неделю или дней за десять до убийства Столыпина. Я был удивлен его появлением, не придавал ему такого значения, какое впоследствии обнаружилось… Я крайне удивился возможности ухода Столыпина, так как в провинции нам казалось, что Столыпин — сила непререкаемая, нам казалось невозможным, чтобы он колебался, шатался или уходил… Распутин объявил мне, что он должен поговорить со мной, так как он послан, как он сказал, — «посмотреть мою душу»…

Председатель. — Кем послан?

Хвостов. — Неопределенно: из Царского послан — посмотреть мою душу… Это казалось мне, в то время непосвященному, несколько смешным, и я с ним поговорил шутовским образом, а потом, через несколько времени, я послал полицмейстера свезти его на вокзал. Распутин уехал…

Председатель. — Вы говорите, вам показалось странным, что это происходило еще при жизни министра внутренних дел, — вы выразили сомнение по этому поводу?

Хвостов. — Я выразил сомнение. Он сказал, что Столыпин должен уйти. Но, по правде сказать, я с ним серьезно не говорил… Я считал, что он одно из духовных развлечений в Царском Селе, но не считал серьезным, чтобы он мог иметь значение при назначении министров… Я знал, что в это время ко мне относился в высшей степени благосклонно бывший император Николай II… Его хорошие отношения ко мне завязались впервые, когда я был губернатором в Вологде и докладывал о возможности соединения вологодских рек с Сибирью чрез Урал. На это обстоятельство я, главным образом, напираю. Это его очень интересовало, я делал ему часто доклады, которые были более радужны, в смысле экономических перспектив, чем все остальное, что делалось в России в это время. Вот этим я обратил на себя его внимание… [4]В предпоследний раз, перед указанным приездом Распутина, я был принят государем сидя, что считалось высшим знаком благоволения. Разговор велся об общих предметах.

Председатель. — А когда в последний раз перед этим визитом Распутина вы были в Царском?

Хвостов. — Я с точностью не помню, но так месяца за полтора… Мне было известно от близких лиц, от иностранных посольств, что обо мне постоянно ведется разговор на охоте… Но этот самый приезд Распутина в высшей степени поразил меня, и я к нему отнесся не серьезно. После этого мне пришлось быть уже в Царском…

Председатель. — Алексей Николаевич, вы говорите, что ваше отношение к этому приезду было отрицательным; но это не избавляет нас от необходимости несколько подробнее остановиться на нем: только ли для этого приезжал Распутин?

Хвостов. — Исключительно для этого.

Председатель. — Какой еще разговор был между вами?

Хвостов. — Разговор исключительно этот. Он сказал: «Приехал посмотреть твою душу»…

Председатель. — Т.-е. только эти несколько слов?

Хвостов. — Он изъявил еще желание посмотреть мою семью… Моей семьи еще не было… Я считал излишним вводить его в мою семью. Я не серьезно к этому отнесся… Тут была ярмарка: она кончалась. Мне было не до того, чтобы беседовать с ним. Я отнесся к этому в высшей степени легко… Когда, через месяц после этого, я приехал сюда, то я увидел ко мне совершенно обратное отношение. Я был принят в высшей степени неприязненно, в высшей степени сухо, что, после предшествующих приемов, мне показалось неособенно приятным. Это послужило основанием тому, что тогда казалось странным: я ушел из губернии, пошел в Государственную Думу… Уйти я сразу не мог, прошло порядочное время, около года: но во всяком случае, в этот промежуток времени, я делал все возможное, чтобы попасть в Государственную Думу по Орловской губернии, и уже все мои мысли были за то, чтобы уйти, — видя, что здесь мне отрезаны все дальнейшие пути…

Председатель. — Что же, уезжая, Распутин какие-нибудь угрозы делал по вашему адресу?

Хвостов. — Болтал по обыкновению: говорил, что он уже обо мне послал телеграмму.

Председатель. — Какого содержания?

Хвостов. — Содержания совершенно не помню в подробностях… Мне потом достали текст (всегда на почте есть свои люди, которые сообщают потом подробное содержание). Но я текста не помню.

Председатель. — Приблизительно, какого содержания? [5]

Хвостов. — Отрицательное ко мне отношение… Что-то такое: «Хотя бог на нем почиет, но чего-то не достает»…

Председатель. — Скажите еще: он вам говорил, от чьего имени из Царского Села он являлся — от отрекшегося государя или от государыни?

There the begining of my code:

## Package ##
library(tm)
library(NLP)
library(slam)
library(FactoMineR)
library(explor)
library(R.temis)
library(zoo)
library(lattice)
library(RcmdrPlugin.temis)
library(tidyverse)

## Importation du corpus

corpus <- import_corpus("./data/CorpusPadenie", format = "txt", language = "ru")

## Importation metadonnees

don <- read.csv2("./data/2019_PDI_M1_MEM_DATA_DOP.csv")

## Association des metadonnees et du corpus

corpus <- set_corpus_variables(corpus, don)
corpus

## Creation d'une copie de secours

corpus2 <- corpus

### Suppression des mots inutiles ###

## Suppressions des noms des intervenants - pour pouvoir identifier les noms utiliser dans les interogatoires - suprressions des seuls intervenants possible du fait de la mise en page.


corpus3 <- tm_map(corpus2, removeWords, c("Председатель. —", "Хвостов"))
removeWords(corpus2[[1]], character(c("Председатель. —", "Хвостов. —")))
corpus2[[1]]
removeWords(corpus2[[1]], "Председатель")


writeCorpus(corpus2, path = "./data/Test", filenames = NULL)

Last part of the result for dput(head(corpus2))

 "1917_08_21_TCHESSKA_7_79_POK_F_A_GOLOVIN.txt", "1917_08_25_TCHESSKA_7_80_DOP_A_A_POLIVANOV.txt", 
"1917_08_25_TCHESSKA_7_81_DOP_V_N_KOKOVTSOV.txt", "1917_09_04_TCHESSKA_7_83_DOP_M_V_RODZIANKO.txt", 
"1917_09_20_TCHESSKA_7_84_DOP_A_A_POLAVINOV.txt", "1917_09_27_TCHESSKA_7_85_DOP_N_B_CHTCHERBATOV.txt", 
"1917_09_27_TCHESSKA_7_86_POK_A_P_LEDNITSKIJ.txt", "1917_10_11_TCHESSKA_7_87_DOP_A_B_LIADOV.txt", 
"1917_10_11_TCHESSKA_7_88_DOP_D_S_CHOUVAEV.txt"), class = "factor"), 
    int_id = structure(1:6, .Label = c("1", "2", "3", "4", 
    "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", 
    "15", "16", "17", "18", "19", "20", "21", "22", "23", 
    "24", "25", "26", "27", "28", "29", "30", "31", "32", 
    "33", "34", "35", "36", "37", "38", "39", "40", "41", 
    "42", "43", "44", "45", "46", "47", "48", "49", "50", 
    "51", "52", "53", "54", "55", "56", "57", "58", "59", 
    "60", "61", "62", "63", "64", "65", "66", "67", "68", 
    "69", "70", "71", "72", "73", "74", "75", "76", "77", 
    "78", "79", "80", "81", "82", "83", "84", "85", "86"), class = "factor"), 
    ind_id = structure(1:6, .Label = c("1", "2", "3", "4", 
    "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", 
    "15", "16", "17", "18", "19", "20", "21", "22", "23", 
    "24", "25", "26", "27", "28", "29", "30", "31", "32", 
    "33", "34", "35", "36", "37", "38", "39", "40", "41", 
    "42", "43", "44", "45", "46", "47", "48", "49", "50", 
    "51", "52", "53", "54", "55", "56", "57", "58", "59", 
    "60"), class = "factor"), ind_nom = structure(c(23L, 
    24L, 43L, 22L, 52L, 9L), .Label = c("Andronikov", "Beletskij", 
    "Belyaev", "Bourtsev", "Chingerev", "Chouvaev", "Chtcheglovitov", 
    "Chtcherbatov", "Chtiourmer", "Djounkovskij", "Dobrovilskij", 
    "Doubenskij", "Frederiks", "Golitsyn", "Golovin", "Goremykin", 
    "Goutchkov", "Guerassimov", "Ignatev", "Ivanov", "Kafafov", 
    "Khabalov", "Khvostov", "Klimovitch", "Kokovtsov", "Komissarov", 
    "Kourlov", "Kryjanovskij", "Lednitskij", "Liadov", "Lodyjenskij", 
    "Lokhtina", "Makarov", "Maklakov", "Manassievitch-Manoujlov", 
    "Markov", "Milioukov", "Naoumov", "Neratov", "Pleve", 
    "Pokrovskij", "Polivanov", "Protopopov", "Rejn", "Rejnbot", 
    "Rodzianko", "Spiridovitch", "Tchaplin", "Tchelnokov", 
    "Tchkhejdze", "Trousevitch", "Vassiliev", "Velepolskij", 
    "Verevkin", "Vissarionov", "Voejkov", "Volkonskij", "Vyroubova", 
    "Zolotarev"), class = "factor"), ind_initiales = structure(c(5L, 
    12L, 3L, 39L, 7L, 9L), .Label = c("AA", "AB", "AD", "AI", 
    "AN", "AP", "AT", "AV", "BV", "DN", "DS", "EK", "FA", 
    "GE", "IF", "IG", "IL", "IM", "IN", "KD", "MA", "MI", 
    "MM", "MS", "MV", "NB", "ND", "NE", "NI", "NN", "NS", 
    "NV", "OA", "PG", "PN", "SE", "SI", "SP", "SS", "VB", 
    "VF", "VL", "VM", "VN"), class = "factor"), int_mois = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L), .Label = c("3", "4", "5", "6", "7", 
    "8", "9", "10"), class = "factor"), int_jour = structure(c(15L, 
    16L, 18L, 19L, 19L, 19L), .Label = c("1", "2", "4", "6", 
    "7", "8", "9", "10", "11", "12", "13", "14", "15", "17", 
    "18", "19", "20", "21", "22", "24", "25", "26", "27", 
    "28", "29", "30", "31"), class = "factor"), int_tome = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L), .Label = c("1", "2", "3", "5", "6", 
    "7"), class = "factor"), int_num = structure(1:6, .Label = c("1", 
    "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", 
    "13", "14", "15", "16", "17", "18", "19", "20", "21", 
    "22", "23", "24", "25", "26", "27", "28", "29", "30", 
    "31", "32", "33", "34", "35", "36", "37", "38", "39", 
    "40", "41", "42", "44", "45", "46", "47", "48", "49", 
    "50", "51", "52", "53", "54", "55", "56", "57", "58", 
    "59", "60", "61", "62", "63", "64", "65", "66", "67", 
    "68", "69", "70", "71", "72", "73", "74", "75", "76", 
    "77", "78", "79", "80", "81", "83", "84", "85", "86", 
    "87", "88"), class = "factor"), dop_pok = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L), .Label = c("DOP", "POK"), class = "factor")), row.names = c(NA, 
6L), class = "data.frame")), class = c("VCorpus", "Corpus"

))


Solution

  • There are several ways to do this. Using sub will only replace the first match with whatever you specify. gsub will replace every instance. You could also check out the package stringi which has several functions for this kind of task. The below example matches everything before the first dash (with a space after it) and replaces it with "". If you wanted to be more conservative you could remove the space after and use trimws if there is an inconsistent spacing pattern after the first dash.

    sub((".* \\- "), "", c("President. - Are you Nikolaj Khvostov?", "Khvostov. - Yes Mr. President."))
    [1] "Are you Nikolaj Khvostov?" "Yes Mr. President."   
    

    EDIT:

    Without understanding your data better we are just guessing, which is why having an example of the data in R is very helpful. However, in theory, these solutions may work depending on your data structure.

    If it is a list this should work:

    text_as_list <- list("President. — Are you Nikolaj Khvostov?", "Khvostov. — Yes Mr. President.")
    
    lapply(text_as_list, sub, pattern = "^.* \\— ", replacement = "")
    [[1]]
    [1] "Are you Nikolaj Khvostov?"
    
    [[2]]
    [1] "Yes Mr. President."
    

    And if it is one long vector, this should work (this uses gsub now):

    long_vector <- c("President. — Are you Nikolaj Khvostov?\nKhvostov. — Yes Mr. President.")
    
    cat(long_vector)
    President. — Are you Nikolaj Khvostov?
    Khvostov. — Yes Mr. President.
    
    long_vector_fixed <- gsub(("Khvostov. \\— "), "", gsub(("President. \\— "), "", long_vector))
    
    cat(long_vector_fixed)
    
    Are you Nikolaj Khvostov?
    Yes Mr. President.
    

    Possible solution using the tm_map function you were using:

    tm_map(corpus2, sub, pattern = "^.* \\— ", replacement = "")