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

时间:2019-02-25 14:06:20

标签: r dplyr tm stringr

我想知道如何从文本字符串中获得唯一的字符数。假设我要寻找字符串中苹果,香蕉,菠萝,葡萄等单词的重复次数。

from openpyxl import load_workbook
from openpyxl import Workbook

# 1) create a workbook
wb = Workbook()
wb.save('my.xlsx')
del wb
# 2) build connection with the just created excel
book = load_workbook('my.xlsx')

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

 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) 

我尝试了这个,但总的来说还是可以的。我想回答为“ 3”。请提出您的想法。

8 个答案:

答案 0 :(得分:7)

您可以使用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

答案 1 :(得分:3)

不太优雅,但是您可以像这样使用str_detect

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

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

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

答案 2 :(得分:3)

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

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

[1] 3

或以缩写形式:

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

答案 3 :(得分:2)

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

Type A user

答案 4 :(得分:2)

还可以:

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

答案 5 :(得分:2)

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

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

答案 6 :(得分:2)

我们可以结合使用stringrstringi

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

答案 7 :(得分:0)

为什么要重新发明轮子? 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()将其标记为单词后,您可以使用向量tokens_select()将结果发送到fruits,以仅选择这些类型。

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

或者,您可能还算过非唯一的出现次数,称为令牌

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