Search code examples
rfor-loopoptimizationletter

Whats the best way to optimize this for loop (letter to number) function?


I have a input stream of cleaned letters that I want to convert into a vector of numbers from 1 to 27 (all letters including space). I can't imagine a nested for loop is the best way to do this though. Is it possible without the loops?

space_letters = append(letters, " ")

text_to_numbers = function (input_stream) {

  input_stream = unlist(strsplit(input_stream, split = ""))

  for(i in 1:length(input_stream)) {
    for(j in 1:length(space_letters) {
      if(input_stream[i] == space_letters[j]) {
        input_stream[i] = j
      }
    }
  }
  return(as.integer(input_stream))
}

Solution

  • Here is a base R alternative using match

    text_to_numbers <- function(ss)
        as.numeric(sapply(strsplit(ss, ""), function(x) match(x, c(letters, " "))))
    
    text_to_numbers("abcdef")
    #[1] 1 2 3 4 5 6
    
    text_to_numbers("the cat")
    #[1] 20  8  5 27  3  1 20
    

    Or the purrr/stringr equivalent:

    library(tidyverse)
    text_to_numbers <- function(ss)
        map_int(str_split(ss, "", simplify = T), ~match(.x, c(letters, " ")))