Return up to the first three words

Viewed 69

Trying to find a way to return the first three words in R. I tried the word function in string_r but it only returns the first three words if the sentence has at least three words. e.g.,


sentences <- c("Jane saw a cat", "Jane sat down", "Jane sat", "Jane")

word(sentences, 1, 3)

This returns Jane saw a, Jane sat down, NA, NA

I would like it to return the first three words, even if the sentence has one or two words. So the output I am looking for is:

This returns Jane saw a, Jane sat down, Jane Sat, Jane

2 Answers

1) stringr Count the number of words in each component of the input and use that or 3, whichever is less, as the number of words to return.

library(stringr)
word(sentences, end = pmin(str_count(sentences, "\\w+"), 3))
## [1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane" 

2) stringr solution 2 Append some dummy words onto the end, take the first 3 words and trim off any dummies left.

sentences %>%
  str_c("@ @ @") %>%
  word(end = 3) %>%
  str_replace(" *@.*", "")
## [1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane"         

3a) Base R The same idea as (1) can be translated to base R like this:

Word <- function(x, end) do.call("paste", read.table(text = x, fill = TRUE)[1:end])

unname(Vectorize(Word)(sentences, end = pmin(lengths(strsplit(sentences, " ")), 3)))
## [1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane"       

3b) The same idea as (2) can be translated to base R like this. Word is from (3a).

sentences |>
  paste("@ @ @") |>
  Word(end = 3) |>
  sub(pattern = " *@.*", replacement = "")
## [1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane"

Update

(1) is simplified and the old (1) is now (2). (3a) and (3b) are now Base R counterparts.

We can split and get the words

sapply(strsplit(sentences, " "), \(x) paste(head(x, 3), collapse=" "))

-output

[1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane"       

Or use a regex

trimws( sub("^((\\w+\\s+){1,3}).*", "\\1", sentences))

-output

[1] "Jane saw a" "Jane sat"   "Jane"       "Jane" 

If we want to use word, then it may need a coalesce

library(stringr)
library(purrr)
library(dplyr)
map(3:1,  word, string = sentences, start = 1) %>%
    exec(coalesce, !!!.)
[1] "Jane saw a"    "Jane sat down" "Jane sat"      "Jane"  
Related