Я добавил еще одну строку в ваш пример, чтобы иметь немного больше вариаций. Это должно быть довольно эффективно:
library(tibble)
library(purrr)
library(dplyr)
library(stringr)
q_data <- tibble(number = 1:2, string = c("COUNTTHESECHARACTERS", "countthesecharacters"))
tmp_data <- map_df(q_data$string, function(s) {
tmp <- t(str_count(s, fixed(LETTERS, ignore_case = TRUE)))
tmp <- as_tibble(tmp, .name_repair = "minimal")
colnames(tmp) <- LETTERS
tmp
}) %>%
bind_rows()
q_data_new <- cbind(q_data, tmp_data)
q_data_new
#> number string A B C D E F G H I J K L M N O P Q R S T U V
#> 1 1 COUNTTHESECHARACTERS 2 0 3 0 3 0 0 2 0 0 0 0 0 1 1 0 0 2 2 3 1 0
#> 2 2 countthesecharacters 2 0 3 0 3 0 0 2 0 0 0 0 0 1 1 0 0 2 2 3 1 0
#> W X Y Z
#> 1 0 0 0 0
#> 2 0 0 0 0
Создано в 2019-10-18 представительным пакетом (v0.3.0)
Есливы смотрите ?str_count
из stringr
, вы можете увидеть еще пару опций, которые могут быть полезны в вашем случае.
Обновление
Я понял только из другого ответа, что вы пытаетесьдля этого нужно посчитать все элементы строки, а не только буквы. В этом случае вы в основном ищете матрицу функций документа:
library(quanteda)
tmp <- q_data$string %>%
tokens("character", remove_separators = FALSE) %>%
dfm() %>%
convert("data.frame") %>%
select(-document) %>%
select(noquote(order(colnames(.)))) %>% # this is just for ordering alpabetically
as_tibble() # just for better comparison to other results
q_data_new <- cbind(q_data, tmp)
q_data_new
Это даже намного быстрее, чем две опции, уже приведенные в ответах. Бенчмаркинг:
q_data <- tibble(number = 1:2000, string = stringi::stri_rand_strings(2000, 20))
stringr <- function(q_data, pattern = c(0:9, letters)) {
tmp_data <- map_df(q_data$string, function(s) {
tmp <- t(str_count(s, fixed(pattern, ignore_case = TRUE)))
tmp <- as_tibble(tmp, .name_repair = "minimal")
colnames(tmp) <- pattern
tmp
}) %>%
bind_rows() %>%
mutate_if(is.integer, as.numeric)
q_data_new <- bind_cols(q_data, tmp_data)
q_data_new
}
tidytext <- function(q_data) {
q_data %>%
group_by(number, string) %>%
unnest_tokens(character, string, token = "characters", drop = FALSE) %>%
count(number, character) %>%
complete(character = letters) %>%
spread(character, n, fill = 0) %>%
ungroup()
}
quanteda <- function(q_data) {
tmp <- q_data$string %>%
tokens("character", remove_separators = FALSE) %>%
dfm() %>%
convert("data.frame") %>%
select(-document) %>%
select(noquote(order(colnames(.)))) %>%
as_tibble()
q_data_new <- cbind(q_data, tmp)
q_data_new
}
результаты
res <- bench::mark(
stringr = stringr(q_data),
tidytext = tidytext(q_data),
quanteda = quanteda(q_data)
)
res
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 stringr 1.82s 1.82s 0.549 17.05MB 3.84
#> 2 tidytext 6.06s 6.06s 0.165 35.17MB 2.31
#> 3 quanteda 56.4ms 70.74ms 13.9 8.75MB 5.95