Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I (re)create an object of type 'language'?

Tags:

r

formula

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 ...

like image 549
Ben Bolker Avatar asked Dec 25 '22 17:12

Ben Bolker


2 Answers

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)
like image 85
Matthew Plourde Avatar answered Dec 28 '22 09:12

Matthew Plourde


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)
like image 45
Joshua Ulrich Avatar answered Dec 28 '22 08:12

Joshua Ulrich