从文本字符串中获取字符串的唯一计数

Posted

技术标签:

【中文标题】从文本字符串中获取字符串的唯一计数【英文标题】:Getting the unique count of strings from a text string 【发布时间】:2019-07-18 23:06:53 【问题描述】:

我想知道如何从文本字符串中获取唯一数量的字符。假设我正在寻找这个字符串中单词 apples、bananas、pineapples、grapes 的重复计数。

 A<- c('I have a lot of pineapples, apples and grapes. One day the pineapples person gave the apples person two baskets of grapes')

 df<- data.frame(A) 

假设我想获取文本中列出的所有水果的唯一计数。

  library(stringr)
  df$fruituniquecount<- str_count(df$A, "apples|pineapples|grapes|bananas")

我试过这个,但我得到了全部计数。我想回答为“3”。请提出你的想法。

【问题讨论】:

我想你得看看tidytext pakcage。这是一本在线书籍:link 【参考方案1】:

不是很优雅,但你可以像这样使用str_detect

sum(str_detect(df$A, "apples"), 
    str_detect(df$A, "pineapples"), 
    str_detect(df$A, "grapes"), 
    str_detect(df$A, "bananas"))

或者,根据下面的 cmets,如果您将所有这些术语放在它们自己的向量中,则可以使用 apply 函数:

fruits <- c("apples", "pineapples", "grapes", "bananas")
sum(sapply(fruits, function(x) str_detect(df$A, x)))

【讨论】:

当我在我的数据集上尝试此操作并创建一个名为 df$fruitcount 的列时,我遇到了一个奇怪的错误。我有很多行,并且计数总是以非常大的数字给出。如果我遗漏了什么,你能建议一下吗? 这可以缩短为sum(sapply(fruits, function(x) str_detect(df$A, x))),用fruits &lt;- c("apples", "pineapples", "grapes", "bananas")【参考方案2】:

您可以使用str_extract_all,然后计算唯一元素的长度。

输入:

A <- c('I have a lot of pineapples, apples and grapes. One day the pineapples person gave the apples person two baskets of grapes')
fruits <- "apples|pineapples|grapes|bananas"

结果

length(unique(c(stringr::str_extract_all(A, fruits, simplify = TRUE))))
# [1] 3

【讨论】:

当我在我的数据集上尝试此操作并创建一个名为 df$fruitcount 的列时,我遇到了一个奇怪的错误。我有很多行,并且计数始终为 5。如果我遗漏了什么,你能建议一下吗? 请在问题的最后分享dput(head(your_dataframe)) 的输出。 是的,我已经在问题中添加了数据和预期的输出 @user3570187 这对我来说似乎是一个不同的故事。由于您现在收到了很多答案,我建议您用刚刚发布的数据询问另一个人,并接受/支持解决此问题的答案。 同意@markus,您的编辑应该是一个不同的问题。【参考方案3】:

也许更好的方法是先分解单词然后计数。

library(tokenizers)
library(magrittr)
df$fruituniquecount <- tokenize_words(A) %>% unlist(.) %>% unique(.) %>% 
       stringr::str_count(., "apples|pineapples|grapes|bananas") %>% sum(.)

【讨论】:

【参考方案4】:

一个基本的可能性可能是:

length(unique(unlist(regmatches(A, gregexpr("apples|pineapples|grapes|bananas", A, perl = TRUE)))))

[1] 3

【讨论】:

【参考方案5】:

也可以:

A <- c('I have a lot of pineapples, apples and grapes. One day the pineapples person gave the apples person two baskets of grapes')

df <- data.frame(A) 

fruits <- c("apples", "pineapples", "grapes", "bananas")

df$count <- sum(tolower(unique(unlist(strsplit(as.character(df$A), "\\.|,| ")))) %in% fruits)

输出:

[1] 3

【讨论】:

【参考方案6】:

好吧,这也是一个无正则表达式的基本 R 解决方案,

sum(unique(strsplit(A, ' ')[[1]]) %in% c('apples', 'pineapples', 'grapes', 'bananas'))
#[1] 3

【讨论】:

【参考方案7】:

我们可以使用stringrstringi的组合:

target<-"apples|pineapples|grapes|bananas"#inspired by @markus ' solution
length(stringi::stri_unique(stringr::str_extract_all(A,target,simplify=TRUE)))
#[1] 3

【讨论】:

【参考方案8】:

为什么要重新发明***? quanteda 包就是为此而构建的。

定义一个水果向量,作为奖励,我使用(默认)glob 模式匹配类型来捕获单数和复数形式。

A <- c("I have a lot of pineapples, apples and grapes. One day the pineapples person gave the apples person two baskets of grapes")
fruits <- c("apple*", "pineapple*", "grape*", "banana*")

library("quanteda", warn.conflicts = FALSE)
## Package version: 1.4.2
## Parallel computing: 2 of 12 threads used.
## See https://quanteda.io for tutorials and examples.

然后,一旦您使用 tokens() 将其标记为单词,您就可以使用您的向量 fruits 将结果发送到 tokens_select() 以仅选择这些类型。

toks <- tokens(A) %>%
  tokens_select(pattern = fruits)
toks
## tokens from 1 document.
## text1 :
## [1] "pineapples" "apples"     "grapes"     "pineapples" "apples"    
## [6] "grapes"

最后,ntype() 会告诉你单词types(唯一单词)的数量,也就是你想要的输出 3。

ntype(toks)
## text1 
##     3

另外,您也可以计算非唯一的出现次数,称为 tokens

ntoken(toks)
## text1 
##     6

这两个函数都被向量化以返回一个命名的整数向量,其中元素名称将是您的文档名称(这里,quanteda 默认为单个文档的“text1”),所以这也很容易工作在大型语料库上高效。

优势? 比正则表达式更容易(并且更易读),而且您可以访问令牌的附加功能。例如,假设您想将单数和复数水果模式视为等价的。您可以在 quanteda 中通过两种方式做到这一点:使用 tokens_replace() 手动将模式替换为规范形式,或者使用 tokens_wordstem() 将水果名称作为词干。

使用tokens_replace()

B <- "one apple, two apples, one grape two grapes, three pineapples."

toksrepl <- tokens(B) %>%
  tokens_select(pattern = fruits) %>%
  tokens_replace(
    pattern = fruits,
    replacement = c("apple", "pineapple", "grape", "banana")
  )
toksrepl
## tokens from 1 document.
## text1 :
## [1] "apple"     "apple"     "grape"     "grape"     "pineapple"
ntype(toksrepl)
## text1 
##     3

使用tokens_wordstem()

toksstem <- tokens(B) %>%
  tokens_select(pattern = fruits) %>%
  tokens_wordstem()
toksstem
## tokens from 1 document.
## text1 :
## [1] "appl"     "appl"     "grape"    "grape"    "pineappl"
ntype(toksstem)
## text1 
##     3

【讨论】:

以上是关于从文本字符串中获取字符串的唯一计数的主要内容,如果未能解决你的问题,请参考以下文章

JCL - 获取给定区域(大型机)中非空格字符的计数

从 UITextView 获取文本

文本消息中字符串的猪计数出现

如何从核心数据中获取最多计数的字符串值

如何从 Oracle 中的字符串中获取唯一字符?

从字符串数组创建唯一组合数组