Consider the following problem: ff
is a formula with some fancy stuff in it; as a result the variables
attribute of terms(ff)
won't contain the raw variables, but rather the fancy stuff, e.g.
ff <- ~I(Age)+poly(q,3)
str(attr(terms(ff),"variables"))
## language list(I(Age), poly(q, 3))
I'm trying to hack this attribute into list(Age,q)
as a language
object. I can get partway there:
(vlist <- lapply(as.list(all.vars(ff)),as.name))
## [[1]]
## Age
## [[2]]
## q
str(vlist)
## List of 2
## $ : symbol Age
## $ : symbol q
but I'm stumped on turning this back into a language
object. I've played around a lot with deparse
, substitute
, bquote
, as.call
... but can't quite get the right incantation, e.g.
deparse(vlist)
## [1] "list(Age, q)" ## character, not language
parse(text=deparse(vlist))
## expression(list(Age, q)) ## expression, not language
as.name(vlist)
## Error in as.name(vlist) :
## (list) object cannot be coerced to type 'symbol'
dput(vlist)
looks good, but it's just printing to the console and not changing the object ...
A little bit more context: I'm running into trouble downstream within model.matrix
, where it checks
reorder <- match(sapply(attr(t, "variables"), deparse2)[-1L],
names(data))
(where deparse2
is a wrapper for deparse
that collapses stuff to a single string). I might be able to get away with setting the variables
attribute to NULL
(so nothing would "not match"), but otherwise I have to set it to something that will be deparse
-able and will match the variables in the new data frame ...
You were on the right track with parse
and deparse
:
(lang <- parse(text=deparse(lapply(all.vars(ff), as.name)))[[1]])
# list(Age, q)
str(lang)
# language list(Age, q)
There might be a better way, but this seems to work:
> (lang <- do.call("call", c("list", lapply(all.vars(ff), as.name)), quote=TRUE))
list(Age, q)
> str(lang)
language list(Age, q)
Here's an alternative, which might be slightly-cleaner:
> (lang <- as.call(c(quote(list), lapply(all.vars(ff), as.name))))
list(Age, q)
> str(lang)
language list(Age, q)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With