Skip to content

Upgrading tokens_replace() to keep tokens and keys togather #2324

Description

@koheiw

We sometimes keep track of tokens matched to dictionary patters but it is not easy (see #2063). tokens_replace() can be used add keys to original tokens (e.g. "United States/Countries") but only with fixed patterns.

require(quanteda)
txt <- c(d1 = "The United States is bordered by the Atlantic Ocean and the Pacific Ocean.",
         d2 = "The Supreme Court of the United States is seldom in a united state.")
toks <- tokens(txt, remove_punct = TRUE)

dict <- dictionary(list(Countries = c("United States", "Federal Republic of Germany"),
                        Cceans = c("Atlantic Ocean", "Pacific Ocean")), tolower = FALSE)

tokens_lookup(toks, dict)
#> Tokens consisting of 2 documents.
#> d1 :
#> [1] "Countries" "Cceans"    "Cceans"   
#> 
#> d2 :
#> [1] "Countries"

To use tokens_replace(), we need to know all the matches beforehand. It is not possible when patterns are glob.

# fixed dictionary

pat <- unlist(dict, use.names = FALSE)
rep <- paste0(pat, "/" ,rep(names(dict), lengths(dict)))
tokens_replace(toks, phrase(pat), rep)
#> Tokens consisting of 2 documents.
#> d1 :
#>  [1] "The"                     "United States/Countries"
#>  [3] "is"                      "bordered"               
#>  [5] "by"                      "the"                    
#>  [7] "Atlantic Ocean/Cceans"   "and"                    
#>  [9] "the"                     "Pacific Ocean/Cceans"   
#> 
#> d2 :
#>  [1] "The"                     "Supreme"                
#>  [3] "Court"                   "of"                     
#>  [5] "the"                     "United States/Countries"
#>  [7] "is"                      "seldom"                 
#>  [9] "in"                      "a"                      
#> [11] "united"                  "state"

# glob dictionary

dict2 <- dictionary(list(Countries = c("* States", "Federal Republic of *"),
                         Cceans = c("* Ocean")), tolower = FALSE)

pat2 <- unlist(dict2, use.names = FALSE)
rep2 <- paste0(pat2, "/" ,rep(names(dict2), lengths(dict2)))
tokens_replace(toks, phrase(pat2), rep2)
#> Tokens consisting of 2 documents.
#> d1 :
#>  [1] "The"                "* States/Countries" "is"                
#>  [4] "bordered"           "by"                 "the"               
#>  [7] "* Ocean/Cceans"     "and"                "the"               
#> [10] "* Ocean/Cceans"    
#> 
#> d2 :
#>  [1] "The"                "Supreme"            "Court"             
#>  [4] "of"                 "the"                "* States/Countries"
#>  [7] "is"                 "seldom"             "in"                
#> [10] "a"                  "united"             "state"

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions