I think you're looking for ifelse, it's a vectorized if.
If your vectors are logical (e.g., T or F), you don't need to test if they're equal to TRUE, they are already either TRUE or FALSE.
c1 = as.logical(sample(c(0, 1), size = 5, replace = T))
c2 = as.logical(sample(c(0, 1), size = 5, replace = T))
c3 = ifelse(c1 & c2, "both are true", "at least one is false")
cbind(c1, c2, c3)
# c1 c2 c3
# [1,] "TRUE" "FALSE" "at least one is false"
# [2,] "FALSE" "FALSE" "at least one is false"
# [3,] "TRUE" "TRUE" "both are true"
# [4,] "TRUE" "TRUE" "both are true"
# [5,] "FALSE" "TRUE" "at least one is false"
Edits:
For your v example, you can do this:
# no need to coerce vectors to vectors with as.vector()
v1 = c(1, 2, 3)
v2 = c(3, 2, 1)
v3 = c(0, 0, 1)
v3 = ifelse(v1 >= 2 & v2 <= 2, 1, v3)
If v1 is >= 2 and v2 <= 2, then 1, else return the original v3 value.
In your comments, you say this:
The And is short circuited when as soon as it encounters one FALSE. In this case, if c1[i] is FALSE, "#update" won't execute regardless of the value of c2[i].
This is correct. It's the meaning of the AND operator in computer science. If you don't like this behavior, perhaps you're looking for OR, which is coded as | (vectorized) or || (single element) in R.