In both solutions you do too much and too little 
as.character(a)
as.integer(infectedvehicle_by_link)
these are both attempts to convert either an integer to a character or a character to an integer respectively , but , they try to do too much, turn everything in the data.frame, they should specifically only try to alter the join variable i.e. link_id.
also, their output is not stored anywhere. R does not typically modify objects in place, so if you don't assign the result of a calculation i.e. use some_name <- your calc with emphasis on <- then you are likely wasting your cpu cycles, as you will calculate but lose the result to the nameless void...
finally, within each loop , you make a b object , the result of a left_join, but this is not handled elegantly vis the for loop that makes it, each time the for loop makes a new b the old b is overwritten, i.e. you may as well have not looped, but just written code with i set to its last value (9)