【发布时间】:2012-03-29 02:34:47
【问题描述】:
我有一个字符串:
str1 <- "This is a string, that I've written
to ask about a question, or at least tried to."
我会怎么做:
1) 统计逗号的个数
2) 统计 '-ion' 的出现次数
有什么建议吗?
【问题讨论】:
我有一个字符串:
str1 <- "This is a string, that I've written
to ask about a question, or at least tried to."
我会怎么做:
1) 统计逗号的个数
2) 统计 '-ion' 的出现次数
有什么建议吗?
【问题讨论】:
stringr 包有一个函数 str_count 可以很好地为您完成这项工作。
library(stringr)
str_count(str1, ',')
[1] 2
str_count(str1, 'ion')
[1] 1
编辑:
因为我很好奇:
vec <- paste(sample(letters, 1e6, replace=T), collapse=' ')
system.time(str_count(vec, 'a'))
user system elapsed
0.052 0.000 0.054
system.time(length(gregexpr('a', vec, fixed=T)[[1]]))
user system elapsed
2.124 0.016 2.146
system.time(length(gregexpr('a', vec, fixed=F)[[1]]))
user system elapsed
0.052 0.000 0.052
【讨论】:
gregexpr() 的时间命中完全来自设置fixed=T(这里根本不需要)。您可能想要为system.time(length(gregexpr('a', vec)[[1]])) 添加时间,这应该与str_count() 的时间几乎相同。这是有道理的,因为str_count() 本质上是gregexpr() 的包装器。
gregexpr 的速度有多慢。
fixed=TRUE 时,我真的没有意识到正则表达式的匹配速度要慢得多。很高兴知道这一点,因此感谢您将这些时间添加到您的帖子中!
data.table j 表达式中,您可以使用dt[,n=str_count(str,'a')] 来获取str 中每行'a' 的数量,但dt[,n= length(gregexpr('a',str)] 不起作用,并且解决方法 (Filter & unlist) 需要很长时间。在我的 data.table j 表达式中切换到 str_count 可以将我的执行时间从几个小时减少到 30 分钟(使用大型数据集)。
数学文本的一般问题需要正则表达式。在这种情况下,您只想匹配特定字符,但要调用的函数是相同的。你想要gregexpr。
matched_commas <- gregexpr(",", str1, fixed = TRUE)
n_commas <- length(matched_commas[[1]])
matched_ion <- gregexpr("ion", str1, fixed = TRUE)
n_ion <- length(matched_ion[[1]])
如果您只想匹配单词末尾的“ion”,那么您确实需要正则表达式。 \b 代表单词边界,需要将反斜杠转义。
gregexpr(
"ion\\b",
"ionisation should only be matched at the end of the word",
perl = TRUE
)
【讨论】:
stringr 库即可。但是请注意length(gregexpr(",", "no commas", fixed = TRUE)[[1]]) 和length(gregexpr(",", "one , comma", fixed = TRUE)[[1]]) 都是1。所以我们需要检查matched_commas[[1]][1] 是否大于0。
这真的是对Richie棉花的答案的适应。我讨厌一遍又一遍地重复相同的功能。此方法允许您在字符串内汇集术语的向量:
str1 <- "This is a string, that I've written to ask about a question,
or at least tried to."
matches <- c(",", "ion")
sapply(matches, function(x) length(gregexpr(x, str1, fixed = TRUE)[[1]]))
# , ion
# 2 1
【讨论】:
str_count(str1, matches)将返回相同的2和1。 span>
另一个选项是stringi
library(stringi)
stri_count(str1,fixed=',')
#[1] 2
stri_count(str1,fixed='ion')
#[1] 1
vec <- paste(sample(letters, 1e6, replace=T), collapse=' ')
f1 <- function() str_count(vec, 'a')
f2 <- function() stri_count(vec, fixed='a')
f3 <- function() length(gregexpr('a', vec)[[1]])
library(microbenchmark)
microbenchmark(f1(), f2(), f3(), unit='relative', times=20L)
#Unit: relative
#expr min lq mean median uq max neval cld
# f1() 18.41423 18.43579 18.37623 18.36428 18.46115 17.79397 20 b
# f2() 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 20 a
# f3() 18.35381 18.42019 18.30015 18.35580 18.20973 18.21109 20 b
【讨论】: