Оптимизировать алгоритм подсчета матрицы для символов в списке слов - PullRequest
2 голосов
/ 25 апреля 2020

У меня есть возможность создать матрицу подсчета для символов в заданном векторе слов и затем построить ее в аккуратном визуальном элементе на основе позиции, взвешенной по количеству. Тем не менее, время выполнения жестоко медленно для больших наборов, в основном потому, что у меня довольно новичок, который работает с O (n ^ 2) из-за вложенных циклов go.

По мере увеличения слов становится дорогим вычислением, вызывающим узкое место в этой функции. Я все еще новичок в R, , но кто-нибудь может предложить оптимизацию где-нибудь в al go или указать мне на векторизованную функцию, уже оптимизированную для чего-то вроде этого ? Я пытаюсь остаться в базе R для минимизации зависимостей, но не сверхкритически.

Ради репрезентации, вот небольшая выборка слов (длина (слово) == 5):

mtx <- matrix(0, byrow=TRUE, nrow=26, ncol=5)
rownames(mtx) <- letters
colnames(mtx) <- c("01", "02", "03", "04", "05")
word_set <- c("clear", "laugh", "cigar", "honda", "tulip", "asset")

for (word in 1:length(word_set)) {

  for (letter in 1:nchar(word_set[word])) {

    chars_in_word <- strsplit(word_set[word], "")[[1]] # Split word into chars
    letter_position <- colnames(mtx)[letter] # Define rowname as letter_position
    letter_match <- rownames(mtx)[match(chars_in_word[letter], rownames(mtx))] # Find which row the char is equal to
    mtx[letter_match, letter_position] <- mtx[letter_match, letter_position] + 1.0000 # Increment tally

  }
}

Мой подход состоит в том, чтобы

  1. Разделить каждое слово на отдельные символы
  2. Сопоставить символ с одной из строк (помеченных a: z), а затем
  3. Увеличение на 1 в согласованной позиции (имена)

Ответы [ 2 ]

2 голосов
/ 25 апреля 2020

Мы можем разбить строку на каждый символ, unlist и поместить в матрицу и посчитать, сколько раз буква встречалась в определенной позиции.

apply(matrix(unlist(strsplit(word_set, "")), nrow = length(word_set), 
      byrow = TRUE), 2, function(x) table(factor(x, levels = letters)))


#  [,1] [,2] [,3] [,4] [,5]
#a    1    1    0    2    1
#b    0    0    0    0    0
#c    2    0    0    0    0
#d    0    0    0    1    0
#e    0    0    1    1    0
#f    0    0    0    0    0
#g    0    0    1    1    0
#h    1    0    0    0    1
#i    0    1    0    1    0
#j    0    0    0    0    0
#k    0    0    0    0    0
#l    1    1    1    0    0
#m    0    0    0    0    0
#n    0    0    1    0    0
#o    0    1    0    0    0
#p    0    0    0    0    1
#q    0    0    0    0    0
#r    0    0    0    0    2
#s    0    1    1    0    0
#t    1    0    0    0    1
#u    0    1    1    0    0
#v    0    0    0    0    0
#w    0    0    0    0    0
#x    0    0    0    0    0
#y    0    0    0    0    0
#z    0    0    0    0    0
1 голос
/ 26 апреля 2020

Мы могли бы использовать mtabulate

library(qdapTools)
mtabulate(strsplit(word_set, ""))

Или использовать table с векторизацией

table(stack(setNames(strsplit(word_set, ""), word_set))[2:1])
#   values
#ind     a c d e g h i l n o p r s t u
#  clear 1 1 0 1 0 0 0 1 0 0 0 1 0 0 0
#  laugh 1 0 0 0 1 1 0 1 0 0 0 0 0 0 1
#  cigar 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0
#  honda 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0
#  tulip 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1
#  asset 1 0 0 1 0 0 0 0 0 0 0 0 2 1 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...