As @Roland explains in the comment thread to this answer, only one arrow is plotted, because geom_segment(arrow=arrow(), mapping = aes(x=b[i,1],y=b[i,2],xend=b[i,3],yend=b[i,4])) is evaluated only when a is plotted. But i only has one value each time a is plotted. During the first time through the loop, i=1 and during the second time i=2. After the loop i also still equals 2. Thus, only one arrow is plotted each time. If, after the loop, you run i=1:2 then you'll get both arrows. On the other hand, if you change i to anything other than 1 and/or 2, you won't get any arrows plotted.
In any case, you can get both arrows without a loop as follows:
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_segment(data=b, arrow=arrow(), aes(x=x1,y=y1,xend=x2,yend=y2))
Question regarding @Roland's first comment: Shouldn't the object a be updated each time through the loop by adding the new geom_segment? For example, if I start with the OP's original a, then after one iteration of the loop,
a = a + geom_segment(arrow=arrow(), aes(x=b[1,1],y=b[1,2],xend=b[1,3],yend=b[1,4]))
Then, after two iterations of the loop,
a = a + geom_segment(arrow=arrow(), aes(x=b[1,1],y=b[1,2],xend=b[1,3],yend=b[1,4])) +
geom_segment(arrow=arrow(), aes(x=b[2,1],y=b[2,2],xend=b[2,3],yend=b[2,4]))
where in each case a means the value of a before the start of the loop. Shouldn't those underlying changes to the object a occur regardless of the when or if a is evaluated?