Look for a word in a sentence with R if not there: drop row

I posted a question a while ago regarding the same project . I'll copy-paste some of the information from this question to clarify what's going on.

I need to loop through all files in a directory and through every line of every file. From these lines, I extract the data I need to create my data. Each filename looks like this.

airbag.WS-U-E-A.lst

      

.

delimiter, .lst

extension (read as text).

Each file contains data per line like

adapter.WR-P-P-F.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml:  <sentence>Een aanpassingseenheid ( adapter ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoereenheden , een koppeleenheid , een geheugeneenheid , een besturingseenheid ( met actieve en passieve elementen en monolitische geïntegreerde schakelingen ) en een elektrische voedingseenheid . &gt;</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml:  <sentence>ID=&quot;1&quot;&gt;Het toestel ( adapter ) draagt zorg voor de overbrenging van gegevens , met een snelheid van 10 Mbps ( megabits per seconde ) , tussen meerdere automatische gegevensverwerkende machines in een digitaal netwerk . &quot; &gt;</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000034.data.ids.xml:  <sentence>Overwegende dat deze sensoren niet zijn ontworpen op de installatie van een gepantserde kabel ; dat de mogelijkheid moet worden geboden dat de gepantserde kabel niet verplicht wordt gesteld voor de aansluiting tussen de sensor en de adapter , maar alleen van de adapter naar het controleapparaat ; dat het bijgevolg noodzakelijk is de verordening dienovereenkomstig te wijzigen ;</sentence>

      

airbag.WS-U-E-A.lst

/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000075.data.ids.xml:  <sentence>ja voor den airbag op te pompen eh :p</sentence>
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000129.data.ids.xml:  <sentence>Dobby , als ze valt heeft ze dan wel al ne airbag hee</sentence>

      

My goal is to create a data tactic that looks like this:

filename             | word | component | leftContext
-------------------------------------------------------------------------------------
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    Een aanpassingseenheid (
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    ID=&quot;1&quot;&gt;Het toestel (
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    [...] tussen de sensor en de
airbag.WS-U-E-A.lst   airbag   WS-U-E-A    ja voor den
airbag.WS-U-E-A.lst   airbag   WS-U-E-A    Dobby , als ze valt heeft ze dan wel al ne

      

  • filename: by scrolling through files and listing all filenames

    files <- list.files(pattern="*.lst", full.names=T, recursive=FALSE)
    d <- data.frame(fileName = unname(sapply(files, basename)), stringsAsFactors = FALSE)
    
          

  • word: extract from filename:

    d$word <- gsub("\\..+", "", d$fileName, perl=TRUE)
    
          

  • : extract from filename:

    d$component <- gsub("^[^.]+.", "", d$fileName, perl=TRUE)
    d$component <- gsub(".lst$", "", d$component, perl=TRUE)
    
          

  • leftContext: Get the offer first, then extract the left context. See this question.

    # New frame, creates e$sentence which holds the sentence
    e <- do.call(rbind, lapply(files, function(x) {
        data.frame(fileName = x, sentence = readLines(x, encoding="UTF-8"), stringsAsFactors = FALSE)
    }))
    # Merge two frames
    df <- merge(d, e, by="fileName", all=TRUE)
    # Get contexts
    contexts <- strsplit(df$sentence, df$node)
    df$leftContext <- sapply(contexts, `[`, 1)
    
          

There. Now I have the result I wanted! Exactly as I wrote above. However , here's the problem.

In my project, I only need sentences that contain word

. Let's say for example we have defined word

as an adapter, but I only have the following suggestions:

Ik zie de adapters niet
Waar is de adapter-aansluiting?
Een aanpassing aan de adapter

      

The output should be:

filename                   | word  | component       | leftContext
-------------------------------------------------------------------------------------
adapter.some-component.lst  adapter  some-component    Een aanpassing aan de 

      

Since the first clause does not match (it contains the trailing one s

) and the second one (it contains additional ones -aansluiting

). So I need an exact word match, but it should be case insensitive.

My guess is that I need to discard lines that do not contain a word at the very beginning of the process. Probably where we define e

. How I see it:

e <- do.call(rbind, lapply(files, function(x) {
    # if SENTENCE contains WORD (case insensitive)
    data.frame(fileName = x, sentence = readLines(x, encoding="UTF-8"), stringsAsFactors = FALSE)
    # endif
}))

      

But honestly, I don't know how to apply it. Here are some sample data:

aids.WR-P-P-D.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-D0000026.data.ids.xml:  <sentence>Het aids-probleem ontstaat door mensen zonder vaste partner, legt de speciale editie uit.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-D0000036.data.ids.xml:  <sentence>Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv.</sentence>

      

aids.WR-PPE.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-E0000002.data.ids.xml:  <sentence>Zuid-Afrika heeft de meeste aids-gevallen ter wereld.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-E0000126.data.ids.xml:  <sentence>Aids is geen pretje.</sentence>

      

aids.WR-P-P-G.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-G0000134.data.ids.xml:  <sentence>Veilige seks kan aids voorkomen.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-G0000288.data.ids.xml:  <sentence>Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit, zoeken miljoenen besmette mensen steeds wanhopiger naar een geneesmiddel.</sentence>

      

Expected Result:

filename          | word | component  | leftContext
-------------------------------------------------------------------------------------
aids.WR-P-P-D.lst  aids   WR-P-P-D      Vorig jaar stierven 3 miljoen mensen aan 
aids.WR-P-P-E.lst  aids   WR-P-P-E      
aids.WR-P-P-G.lst  aids   WR-P-P-G      Veilige seks kan 

      

Others do not exactly match the word (in which case they are followed -sometext

, but the trait does not always exist! Words such as aidsprobleem

should also be excluded. The second line in the output does not have a leftContext, because nothing precedes it in the data.

I hope I've made it clear what I need. I'm most interested in excluding lines where the word is not found in the sentence (case insensitive).


I tried to apply the tospig solution below. df

is the final dataframe I already have, which looks something like this (just a visual example):

fileName         | node | component | precedingWord | leftContext                               | sentence 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
aids.WR-P-P-D.lst  aids   WR-P-P-D    Het             Het                                         Het aids-probleem ontstaat door mensen zonder vaste partner, [...]
aids.WR-P-P-D.lst  aids   WR-P-P-D    aan             Vorig jaar stierven 3 miljoen mensen aan    Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv.
aids.WR-P-P-E.lst  aids   WR-P-P-E    meeste          Zuid-Afrika heeft de meeste                 Zuid-Afrika heeft de meeste aids-gevallen ter wereld.
aids.WR-P-P-E.lst  aids   WR-P-P-E                                                                Aids is geen pretje.
aids.WR-P-P-G.lst  aids   WR-P-P-G    kan             Veilige seks kan                            Veilige seks kan aids voorkomen.
aids.WR-P-P-G.lst  aids   WR-P-P-G    de              Want naarmate de                            Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit [...]

      

Then I try to delete the lines node

not found in sentence

(in this case 1, 3 and 6):

pattern <- c(" - .*","^- .*"," -$")
pattern <- gsub("-",df$node,pattern)
pattern <- paste0(pattern, collapse="|")

df1 <- df[grepl(pattern, df$sentence, ignore.case=TRUE),]

      

However gsub gives an error:

In gsub ("-", df $ node, pattern): the 'replacement' argument has a length> 1 and only the first element will be used

Which seems logical to me: nowhere do I tell R that the replacement should occur in every word, for example. that aids should only be sought in sentences with df $ node = aids.

+3


source to share


1 answer


Following this from a different angle to my (now deleted) previous answer,

given an example of your final dataframe e

t1 <- "Het aids-probleem ontstaat door mensen zonder vaste partner, legt de speciale editie uit"
t2 <- "Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv"
t3 <- "Zuid-Afrika heeft de meeste aids-gevallen ter wereld."
t4 <- "Aids is geen pretje."
t5 <- "Veilige seks kan aids voorkomen."
t6 <- "Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit"
node <- rep("aids",6)
t7 <- "Waar is de adapter-aansluiting?"
t8 <- "Een aanpassing aan de adapter"
node <- c(node, rep("adapter",2))  

e <- data.frame(node = node, sentence = c(t1, t2, t3, t4, t5, t6, t7, t8), stringsAsFactors=FALSE)

      

You can multiply and use regex for this, not when you read in your files.



Something like:

## vector of regex
e$pattern <- paste0(" ", e$node, " .*|^",e$node,".*| ", e$node, "$")

## create logical subset of rows matching the pattern
e$log <- apply(e, 1, function(x) {
  grepl(x["pattern"],x["sentence"],ignore.case=TRUE) 
})

## subset by 'TRUE'
e <- e[e$log,]

## create leftContext
e$leftContext <- apply(e, 1, function(x){
  sub(x["pattern"], "", x["sentence"], ignore.case=TRUE) 
})

      

What gives

> e[,c("node","sentence","leftContext")]
     node                                                                             sentence
2    aids Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv
4    aids                                                                 Aids is geen pretje.
5    aids                                                     Veilige seks kan aids voorkomen.
8 adapter                                                        Een aanpassing aan de adapter
                           leftContext
2 Vorig jaar stierven 3 miljoen mensen aan
4                                         
5                         Veilige seks kan
8                    Een aanpassing aan de

      

0


source







All Articles