0

What do I have in R?

The following vectors:

N <- c('a','b')
M <- c('x','y')

The goal.

While keeping the vectors intact (I do not wish to combine them into a matrix), I would like to call the elements of the vectors in the following pairwise fashion:

"a" "x" "b" "y"

The code so far.

I've tried to use a for loop, but in the way it is written below, it is read as a nested for loop:

for (i in M) for (j in N)  { 
 print(i)
 print(j)
}

Which results in:

"a" "x" "a" "y" "b" "x" "b" "y"

What I've searched for.

Using search terms as multiple indices, for loops, and double loops, I was only able to find information on nested loops. The use of flow commands did not help me in my quest.

The real goal.

I would like to add one line of text into an image. The textual tags are stored in a single vector and the images are as well. The code I have so far works, except for calling the elements of the vectors in the pairwise fashion explained above. There are plenty of pictures and life's too short to do it all by hand.

Any help would be greatly appreciated!

Stijn

  • base on your explanation, you should look into `Map` this takes pairwise (or more) arguments from vectors (or lists) and applies a function to them, and returns a list. If you truly want to combine an image and text and then print it out (to file or whatever), then a `for` loop will be your best bet. – lmo Apr 30 '17 at 15:27

4 Answers4

3

We can rbind the vectors and then concatenate

c(rbind(M, N))
#[1] "x" "a" "y" "b"

Or another option is order based on the sequence of vector

c(M, N)[order(c(seq_along(M), seq_along(N)))]
#[1] "x" "a" "y" "b"

If we really need a for loop, then preallocate a list with length equal to the number of elements in 'M', loop through the sequence of one of the vectors, and assign the concatenate elements of 'M' and 'N' based on the index to the list element and unlist it

l1 <- vector("list", length(M))
 for(i in seq_along(M)){
   l1[[i]] <- c(M[i], N[i])
 }
unlist(l1)
#[1] "x" "a" "y" "b"
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Quick answer! But is there no alternative with the use of a for loop? See "The real goal" paragraph for the reason why. –  Apr 30 '17 at 09:51
  • @Stijn I added one more option with `seq_along`. I think `for` loop will be slow – akrun Apr 30 '17 at 09:52
  • I understand the for loop will be slow, but I don't know how else I can first load an image (from vector 1) and subsequently add the text (from vector 2). Is there any way to use a for loop in this way, with multiple indices? –  Apr 30 '17 at 09:56
  • @ akrun, thank you for the help. Combining your and @Majed's answer, I was able to simply loop with the vectors' index numbers using the loop I already had. –  Apr 30 '17 at 12:14
  • similar to the Q, I have a custom function.where element 1 from N, and element 2 from vec M is an input the function. Tried the mapply above and it did not work, do you have any dplyr or lapply solution ? – user5249203 Jul 22 '20 at 06:23
0

The way it is explained in the "real goal", each element in the "textual tags" vectors corresponds to one in the "images vector". If that's correct, isn't the solution as simple as (given that both vectors have the same length):

for (i in textTags)
  addThisToThat(textTags[i], images[i])
MJZ
  • 174
  • 13
0

Do you know about lapply? In the purrr package you can find its equivalent: map. You can also find map_2 there, which Loops over two vectors syncronously. Syntax is like map_2(vec1, vec2, ~some_function_of(.x, .y))

Taz
  • 546
  • 5
  • 9
  • @ Taz, thanks for that; I know it can be a lot faster than loops. Will have a look into that. –  Apr 30 '17 at 12:11
0

For other people with this question, I recommend using the base R function mapply. Unlike a for loop, it automatically defines variables n and m for each loop.

mapply(N, M, function(n, m) {
   print(n)
   print(m)
})

Note, this does not work if you want to print something on each loop.

Jeff Bezos
  • 1,929
  • 13
  • 23