If you reshape to long form, you can filter on a single column instead of iterating over columns:
library(tidyverse)
set.seed(47) # for reproducible sampling
df <- tibble(id = 1:10,
a = round(runif(10)),
b = round(runif(10)))
df2 <- df %>%
gather(letter, value, a:b) %>%
filter(value == 1)
df2
#> # A tibble: 11 x 3
#> id letter value
#> <int> <chr> <dbl>
#> 1 1 a 1.
#> 2 3 a 1.
#> 3 4 a 1.
#> 4 5 a 1.
#> 5 6 a 1.
#> 6 9 a 1.
#> 7 10 a 1.
#> 8 2 b 1.
#> 9 4 b 1.
#> 10 5 b 1.
#> 11 6 b 1.
Really, you probably want your data to stay in a data frame like this, but you can use split to make a list of vectors:
df2 %>% {split(.$id, .$letter)}
#> $a
#> [1] 1 3 4 5 6 9 10
#>
#> $b
#> [1] 2 4 5 6
or data frames, depending on how you subset:
df2 %>% {split(.['id'], .$letter)}
#> $a
#> # A tibble: 7 x 1
#> id
#> <int>
#> 1 1
#> 2 3
#> 3 4
#> 4 5
#> 5 6
#> 6 9
#> 7 10
#>
#> $b
#> # A tibble: 4 x 1
#> id
#> <int>
#> 1 2
#> 2 4
#> 3 5
#> 4 6
The braces are necessary so the data piped in does not get passed to the first parameter.
Another way to do the same thing is to use nest to make a list column (effectively grouped by letter), which you can then extract:
df2 %>%
nest(id) %>%
pull(data)
#> [[1]]
#> # A tibble: 7 x 1
#> id
#> <int>
#> 1 1
#> 2 3
#> 3 4
#> 4 5
#> 5 6
#> 6 9
#> 7 10
#>
#> [[2]]
#> # A tibble: 4 x 1
#> id
#> <int>
#> 1 2
#> 2 4
#> 3 5
#> 4 6
Again, the data frame form is more useful in the long run.