-4
y <- c()
for( position in c("cannon","jackson","benford","paws","moxie") ) {
n <- nchar(position)
y[position] <- letters[n]
}
y`

This is the shortcut code but I am running into difficulties when I try to to make the expanded code. There needs to be 15 lines of code.

markus
  • 25,843
  • 5
  • 39
  • 58
lop
  • 1
  • 1
  • 1
    Welcome to Stack, I am not understanding the question would you mind expanding on it a little? – Chabo Sep 21 '18 at 21:43
  • 1
    What are you trying to accomplish, and what are you encountering while using this code? – Anonymous coward Sep 21 '18 at 21:48
  • the code I posted is the shortcut and I am needing to write out the extended code not using a for loop function. – lop Sep 21 '18 at 21:54
  • @lop Can you explain what you mean by "the extended code"? You might also show expected output based on a minimal example. – markus Sep 21 '18 at 21:58
  • @markus Writing out the 15 lines of code for which the for loop is serving as a shortcut. – lop Sep 21 '18 at 22:08
  • But how should we know about the 15 lines of code? – markus Sep 21 '18 at 22:09
  • @markus The following `for` loop goes through the words cannon, jackson, benford, paws, and moxie and defines elements of `y`, a named vector to be the letter of the alphabet in the position equal to the number of characters of each word (cannon has 6 letters, and the 6th letter of the alphabet is f). – lop Sep 21 '18 at 22:12
  • I see that. What I don't see are the 15 lines of code. What are you trying to achieve? – markus Sep 21 '18 at 22:13
  • @markus I'm the one that has to create the 15 lines of code to show the same thing as the for loop is showing. – lop Sep 21 '18 at 22:15
  • Everyone is confused since you usually do not make code more inefficient, but I am guessing this is some assignment so you can understand the logic. You want to write the code that has the same functionality but not in a for-loop, meaning it is likely to be longer, ~15 for your assignment? – Chabo Sep 21 '18 at 22:19
  • Is this a homework? Instead of a for loop, why not vectorize your code and do `letters[nchar(c("cannon","jackson","benford","paws","moxie"))]` – markus Sep 21 '18 at 22:19
  • @Chabo yes this is for an assignment for us to better understand it. I'm just having trouble going backwards once a for loop is given. – lop Sep 21 '18 at 22:24
  • @markus it is for us to better understand how to work a for loop backwards – lop Sep 21 '18 at 22:33

1 Answers1

1

Given a character vector

chars <- c("cannon", "jackson", "benford", "paws", "moxie")

the task is to find the number of characters of each of elements of chars. Then we want to take this result and subset letters accordingly.

1st approach: copy&paste (don't do that)

nchar_cannon <- nchar(chars[1])
nchar_jackson <- nchar(chars[2])
nchar_benford <- nchar(chars[3])
nchar_paws <- nchar(chars[4])
nchar_moxie <- nchar(chars[5])

letter_cannon <- letters[nchar_cannon]
letter_jackson <- letters[nchar_jackson]
letter_benford <- letters[nchar_benford]
letter_paws <- letters[nchar_paws]
letter_moxie <- letters[nchar_moxie]

out <- c(letter_cannon,
         letter_jackson,
         letter_benford,
         letter_paws,
         letter_moxie)
setNames(out, chars)

I guess this is what you are trying to avoid using a ...

2nd approach: for-loop (is fine, though does not enjoy the best reputation in the R community)

out <- c()
for( position in c("cannon","jackson","benford","paws","moxie") ) {
n <- nchar(position)
out[position] <- letters[n]
}
out

3rd approach: use a functional

sapply(chars, function(x) letters[nchar(x)])

4th approach: vectorization (recommended)

setNames(letters[nchar(chars)], chars)

benchmark

library(microbenchmark)
chars_long <- c(replicate(1e6, chars))

benchmark <- microbenchmark(
  loop_fun = loop_fun(chars_long),
  functional_fun = functional_fun(chars_long),
  vectorize_fun = vectorize_fun(chars_long),
  times = 100L
)

autoplot(benchmark)

enter image description here

#Unit: seconds
#           expr       min        lq      mean    median        uq      max neval
#       loop_fun  7.217346  8.142811  9.481697  9.431999 10.472183 13.54128   100
# functional_fun 10.540376 12.064269 13.062617 12.873895 13.738929 17.90349   100
#  vectorize_fun  1.227648  1.310427  1.450161  1.370944  1.552207  2.00134   100

Functions used in the benchmark

loop_fun <- function(x) {
  out <- c()
  for( position in x ) {
    n <- nchar(position)
    out[position] <- letters[n]
  }
  out
}

functional_fun <- function(x) {
  sapply(x, function(y) letters[nchar(y)])
}

vectorize_fun <- function(x) {
  setNames(letters[nchar(x)], x)
}
markus
  • 25,843
  • 5
  • 39
  • 58