Using JonSpring's sample data, here's a method that does not rely on pivoting.
library(dplyr)
findB <- 1000
df %>%
  mutate(
    x = apply(
      mapply(function(a, b) if_else(b == findB, a, a[NA]), 
             pick(starts_with("a")), pick(starts_with("b"))),
      1, function(z) na.omit(z)[1])
  )
#   ID a1 a2   b1   b2  x
# 1  1  0 11 1000  996  0
# 2  2  1 12 1001  997 NA
# 3  3  2 13 1002  998 NA
# 4  4  3 14 1003  999 NA
# 5  5  4 15 1004 1000 15
This can be done in base R without difficulty,
findB <- 1000
df$x <- apply(
  mapply(function(a, b) if_else(b == findB, a, a[NA]),
         subset(df, select = startsWith(names(df), "a")), subset(df, select = startsWith(names(df), "b"))),
  1, function(z) na.omit(z)[1]
)
The use of a[NA] is because there are over six "types" of NA, and it is generally better to be type-safe. For instance, while class(a) here (inside the function) is "integer", if we used just class(NA) then we get "logical", any some type-safe functions tend to complain/fail with this. The use of a[NA] in there will be a vector of NA_integer_ (one of the six) the same length as the original a.