You can continue to parse out your dag_str2 to create your formula notation.
library(dplyr)
library(tidyr)
df <- tibble(str = unlist(dag_str2)) %>%
separate(str, c("lhs", "rhs"), sep = "<-") %>%
group_by(lhs) %>%
summarize(rhs = paste(rhs, collapse = "+"), .groups = "drop") %>%
mutate(f = paste(lhs, rhs, sep = "~"))
From here, you can convert to an actual formula easily if you need to.
lapply(df$f, as.formula)
# [[1]]
# A ~ D + G + Q
# <environment: 0x000001af8db7fa20>
#
# [[2]]
# D ~ G
# <environment: 0x000001af8db7fa20>
Edit Based on Comments
Here is one way to pull out the terms for which you want to build an intercept for.
There is just one new line, bind_rows(). This adds rows for the terms that are in the RHS, but not in the LHS.
df <- tibble(str = unlist(dag_str2)) %>%
separate(str, c("lhs", "rhs"), sep = "<-") %>%
bind_rows(tibble(lhs = setdiff(.$rhs, .$lhs),
rhs = "1")) %>%
group_by(lhs) %>%
summarize(rhs = paste(rhs, collapse = "+"), .groups = "drop") %>%
mutate(f = paste(lhs, rhs, sep = "~"))