Updating an inventory with R using apply functions
You can indeed use vectorization. Create two vectors of indices (or booleans like I did) to identify the rows of the master that need to be updated. To find the corresponding row from the new, you can use the match function like I did.

## Update inventory
if (all(new$book %in% master$book)) {
   idx.map       &lt;- match(master$book, new$book)
   is.match      &lt;- master$book %in% new$book
   checking.out  &lt;- is.match &amp; master$status == "IN"
   checking.in   &lt;- is.match &amp; master$status == "OUT"
   master$status[checking.out]  &lt;- "OUT"
   master$status[checking.in ]  &lt;- "IN"
   master$student[checking.out] &lt;- as.character(new$student[idx.map[checking.out]])
   master$student[checking.in ] &lt;- NA
   master$date[checking.out]    &lt;- as.character(new$date[idx.map[checking.out]])
   master$date[checking.in ]    &lt;- NA
} else {
   stop("At least one book not found in database")
}


You will notice another improvement: everywhere I am referring to columns using their name, for example, master$student instead of their index like master[..., 3]. It makes the code more readable and easier to maintain (Imagine what would happen if suddenly a column was inserted at the beginning of master: you would have to modify all your indices...)