Why does `str_extract_all` return NA for non-matches?

Viewed 715

I have a very large dataset containing more than half a million utterances from conversation. I'd like to extract those words that contain the string well, such as jewellery or dwelling but not the word well itself. I'm using str_extract_all:

library(stringr)
unlist(str_extract_all(X, "\\b\\w+well\\w+\\b"))

The extraction does work but it also returns NA for each utterance where the pattern does not match. I get an output like this:

...
[568] NA          NA          NA          NA          "jewellery" NA          NA          NA          NA 
....

I can prevent getting NAs by subsetting the data on the pattern to be extracted:

unlist(str_extract_all(X[grepl("\\b\\w+well\\w+\\b", X)], "\\b\\w+well\\w+\\b"))

But doing so is unwieldy and, curiously, the extraction using str_extract_all works just fine in another smaller dataset here called sample, structured just like the big dataset:

sample <- c("well you can use that for any argument then",
            "he said well what have , what am i gon na get him poor feller !",
            "that 's what he was doing , hoping i was asleep .",
            "was hoping this afternoon to get the curtain rail .",
            "you do tend to skip by if there 's another one that you think oh well",
            "but the swellings gone down mostly i 've got gloves","is n't he ? sort of jewellery you see .",
            "since you done it we 've been looking in jewellers ' shops")

unlist(str_extract_all(sample, "\\b\\w+well\\w+\\b"))
[1] "swellings" "jewellery" "jewellers"

Why does it work here all of a sudden and, more importanly, how can I tweak the extraction of the target words from the large dataset so that only raw matches are listed but not NA?

1 Answers

In case you have NA in the vector stringr::str_extract_all will return NA:

sample[1] <- NA
unlist(stringr::str_extract_all(sample, "\\b\\w+well\\w+\\b"))
#[1] NA          "swellings" "jewellery" "jewellers"

To get rid of NA you can remove NA using is.na like:

unlist(stringr::str_extract_all(sample[!is.na(sample)], "\\b\\w+well\\w+\\b"))
#[1] "swellings" "jewellery" "jewellers"

or you use gregexpr and regmatches from base:

unlist(regmatches(sample, gregexpr("\\b\\w+well\\w+\\b", sample)))
#[1] "swellings" "jewellery" "jewellers"
Related