Binding dataframes or columns based on containing values

Hello,

Currently I have a point where only a subset of items are produced between a to e. I likely will always end up with at least 2 of the 5 but not always the same. I have created a dummy example where we only have a and b containing values. I want a solution where we bind those that qualify to a data.frame while dropping the rest. As you can see so far it is working except where we have NAs for column 3.

I want to have some way to drop these during the do.call and also to retain their original names (hence column 1 should be called a and column 2 should be called b it shoudl work on those that qualify of course).

a <- factor(
  x = c(0,1,1,0,1,1,0),
  levels = c(0, 1),
  labels = c("No", "Yes"))



b <- factor(
  x = c(0,1,2,2,1,1,0),
  levels = c(0, 1, 2),
  labels = c("No", "Yes", "Maybe"))


c <- NA

d <- NULL



df_list <- list()
df_list[[1]] <- a
df_list[[2]] <- b
df_list[[3]] <- c
df_list[[4]] <- d
df_list[[5]] <- e
#> Error in eval(expr, envir, enclos): object 'e' not found

do.call(cbind,df_list)
#>      [,1] [,2] [,3]
#> [1,]    1    1   NA
#> [2,]    2    2   NA
#> [3,]    2    3   NA
#> [4,]    1    3   NA
#> [5,]    2    2   NA
#> [6,]    2    2   NA
#> [7,]    1    1   NA

Created on 2020-10-11 by the reprex package (v0.3.0)

The NA aspect can be solved by filtering with is.na() beforehand. For the names, the only simple way I can think of is by manually setting them as names. Shouldn't be a problem if they're always called a, b, c and d.

a <- factor(
  x = c(0,1,1,0,1,1,0),
  levels = c(0, 1),
  labels = c("No", "Yes"))

b <- factor(
  x = c(0,1,2,2,1,1,0),
  levels = c(0, 1, 2),
  labels = c("No", "Yes", "Maybe"))

c <- NA

d <- NULL



df_list <- list(a=a,b=b,c=c,d=d)

non_na_list <- df_list[!is.na(df_list)]

do.call(cbind, non_na_list)
#      a b
# [1,] 1 1
# [2,] 2 2
# [3,] 2 3
# [4,] 1 3
# [5,] 2 2
# [6,] 2 2
# [7,] 1 1

for data.frames (as opposed to matricies) here is an option:

a <- factor(
  x = c(0,1,1,0,1,1,0),
  levels = c(0, 1),
  labels = c("No", "Yes"))

b <- factor(
  x = c(0,1,2,2,1,1,0),
  levels = c(0, 1, 2),
  labels = c("No", "Yes", "Maybe"))

c <- NA

d <- NULL


df_list <- list()
df_list[[1]] <- a 
df_list[[2]] <- b
df_list[[3]] <- c
df_list[[4]] <- d
df_list[[5]] <- e

names(df_list) <- c(letters[seq_along(df_list)])

(mydf <- as_tibble(df_list) %>% select_if(shiny::isTruthy))