R подсчитывает количество запятых и строк

У меня есть строка:

    str1 <- "This is a string, that I've written 
        to ask about a question, or at least tried to."

Как бы я:

1) подсчитайте количество запятых

2) подсчитывают вхождения '-ion'

Любые предложения?

Ответ 1

Пакет stringr имеет функцию str_count, которая делает это для вас красиво.

library(stringr)

str_count(str1, ',')
[1] 2
str_count(str1, 'ion')
[1] 1

EDIT:

Потому что мне было любопытно:

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 

Ответ 2

Общая проблема математического текста требует регулярных выражений. В этом случае вы просто хотите сопоставить определенные символы, но функции для вызова одинаковы. Вы хотите 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
)

Ответ 3

Это действительно адаптация ответа Ричи Коттона. Я ненавижу повторять одну и ту же функцию снова и снова. Этот подход позволяет вам комбинировать вектор терминов для соответствия внутри строки:

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 

Ответ 4

Другой вариант: 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