Мы предполагаем, что если в vec
нет 1, то мы должны использовать правую часть от 1, а если в vec
нет -1, то левая сторона пуста.
Каждая из альтернатив создает строку символов, но если требуется объект класса формулы, используйте formula(s)
, где s
- эта строка.
1) вставьте каждую сторону Подставьте имена, соответствующиеvec -1 дает LHS и вставляет / сворачивает их и делает то же самое с vec 1, давая RHS и вставляет их вместе с ~.Если бы мы знали, что в vec
есть хотя бы один 1, мы могли бы опустить оператор if
.Из представленных здесь решений это представляется наиболее простым.
nms <- names(df)
LHS <- paste(nms[vec == -1], collapse = "+")
RHS <- paste(nms[vec == 1], collapse = "+")
if (RHS == "") RHS <- "1"
paste0(LHS, "~", RHS)
## [1] "a+b~d+e"
2) sapply Альтернативно объедините линии LHS и RHS в одну sapply
.Если бы мы знали, что в vec
есть хотя бы один 1, то мы могли бы упростить код, пропустив оператор if
.Этот подход короче (1).
sa <- sapply(c(-1, 1), function(x) paste(names(df)[vec == x], collapse = "+"))
if (sa[2] == "") sa[2] <- "1"
paste0(sa[1], "~", sa[2])
## [1] "a+b~d+e"
3) tapply Мы можем поочередно объединить линии LHS и RHS в одну tapply
, например:
ta <- tapply(names(df), vec, paste, collapse = "+")
paste0(if (any(vec == -1)) ta[["-1"]], "~", if (any(vec == 1)) ta[["1"]] else 1)
## [1] "a+b~d+e"
Если мы знали, что -1 и 1 появляются по крайней мере один раз в vec
, то мы можем упростить последнюю строку до:
paste0(ta[["-1"]], "~", ta[["1"]]])
## [1] "a+b~d+e"
В целом, этот подход самый короткий, если мы можем гарантировать, чтобудет по крайней мере один 1 и по крайней мере один -1, но в противном случае обработка краевых случаев кажется несколько громоздкой по сравнению с другими подходами.