[R-sig-ME] [R] understanding I() in lmer formula
Ben Bolker
bbolker at gmail.com
Wed Jun 14 16:40:18 CEST 2017
On 17-06-14 08:59 AM, Don Cohen wrote:
>
> > The expression `~z.n.males` is a unary formula, i.e. a language
> > object, so it's not a data object much less a numeric data
> > object. The `*` operator does not have a method for such an object
> > as the second argument.
>
> ok, so the next question is where this comes from
Something is getting mangled internally. One of the reasons you're
not getting much useful advice here is that this is new to us -- I've
never seen anything like this happen before. I keep making guesses
based on the differences between your example and the stuff people
normally try to do (I() inside random effects term, long random-effects
term), but so far my guesses haven't panned out. This is the reason we
keep asking for a **reproducible** example; if I could run this example
myself I could almost certainly figure out what's going on, but remote
debugging is really hard.
>
> > It appears that trying to use I() on an expression with a
> > multiplication operator was not something that was anticipated as
> > having a sensible meaning.
It is perfectly sensible: it just means "multiply these two terms
together, using the normal arithmetic meaning of *, rather than
composing their interaction"). However, if this term is indeed causing a
problem, it can be worked around by defining a new variable rather than
constructing it on the fly (this is what I suggested in my previous error).
>
> That would cause it to get the error in all those other cases where
> there is no error.
> Notice that the difference between getting the error and not getting
> it is not in the I() term - that's the same in both cases.
>
> > I'm not sure what this was supposed to be doing but perhaps you
> > wanted the interaction()-function rather than the as.is function?
>
> What all this is supposed to mean is another topic I'd also like to
> discuss. I did not write the original formula. I'm just trying to
> make small changes to it to see the effects. Or at least I WAS trying
> to make small changes. I had already made rather large changes to
> simplify the example in my first post.
OK, I've been able to reproduce this (code below), will dig in and let
you know what I find.
----
form <- log.corti~z.n.fert.females*z.n.males+
is.alpha2*(z.infanticide.susceptibility+z.min.co.res+z.co.res+z.log.tenure)+
z.xtime+z.age.at.sample+sin.season+cos.season+
(1 #+z.n.fert.females
+z.n.males
+is.alpha2.subordinate
+z.infanticide.susceptibility
+z.min.co.res
+z.log.tenure
+z.co.res
## +z.xtime
+z.age.at.sample
+sin.season
+cos.season+
I(z.n.fert.females*z.n.males)+
I(is.alpha2.subordinate*z.min.co.res)+
## I(z.co.res*is.alpha2.subordinate)
I(is.alpha2.subordinate*z.co.res)
## +int.is.a.log.ten
||monkeyid)
xvars <- setdiff(all.vars(form),"monkeyid")
dd <- data.frame(matrix(rnorm(1000*length(xvars)),ncol=length(xvars)))
names(dd) <- xvars
dd$monkeyid <- factor(rep(1:20,50))
library(lme4)
parse <- lFormula(form, data=dd)
>
> I think this shows that the problem is in parsing:
> parse <- lFormula(formula = log.corti~z.n.fert.females*z.n.males+
> is.alpha2*(z.infanticide.susceptibility+z.min.co.res+z.co.res+z.log.tenure)+
> z.xtime+z.age.at.sample+sin.season+cos.season+
> (1 #+z.n.fert.females
> +z.n.males
> +is.alpha2.subordinate
> +z.infanticide.susceptibility
> +z.min.co.res
> +z.log.tenure
> +z.co.res
> # +z.xtime
> +z.age.at.sample
> +sin.season
> +cos.season+
> I(z.n.fert.females*z.n.males)+
> I(is.alpha2.subordinate*z.min.co.res)+
> # I(z.co.res*is.alpha2.subordinate)
> I(is.alpha2.subordinate*z.co.res)
> # +int.is.a.log.ten
> ||monkeyid), data=fe.re.xx$data)
> + + + + + + + + + + + + + + + + + + + Error in is.alpha2.subordinate * ~z.co.res :
> non-numeric argument to binary operator
>
> whereas switching the order of the * arguments
> parse <- lFormula(formula = log.corti~z.n.fert.females*z.n.males+
> is.alpha2*(z.infanticide.susceptibility+z.min.co.res+z.co.res+z.log.tenure)+
> z.xtime+z.age.at.sample+sin.season+cos.season+
> (1 #+z.n.fert.females
> +z.n.males
> +is.alpha2.subordinate
> +z.infanticide.susceptibility
> +z.min.co.res
> +z.log.tenure
> +z.co.res
> # +z.xtime
> +z.age.at.sample
> +sin.season
> +cos.season+
> I(z.n.fert.females*z.n.males)+
> I(is.alpha2.subordinate*z.min.co.res)+
> I(z.co.res*is.alpha2.subordinate)
> # I(is.alpha2.subordinate*z.co.res)
> # +int.is.a.log.ten
> ||monkeyid), data=fe.re.xx$data)
> + + + + + + + + + + + + + + + + + + + >
>> parse$formula
> log.corti ~ z.n.fert.females * z.n.males + is.alpha2 * (z.infanticide.susceptibility +
> z.min.co.res + z.co.res + z.log.tenure) + z.xtime + z.age.at.sample +
> sin.season + cos.season + ((1 | monkeyid) + (0 + z.n.males |
> monkeyid) + (0 + is.alpha2.subordinate | monkeyid) + (0 +
> z.infanticide.susceptibility | monkeyid) + (0 + z.min.co.res |
> monkeyid) + (0 + z.log.tenure | monkeyid) + (0 + z.co.res |
> monkeyid) + (0 + z.age.at.sample | monkeyid) + (0 + sin.season |
> monkeyid) + (0 + cos.season | monkeyid) + (0 + I(z.n.fert.females *
> z.n.males) | monkeyid) + (0 + I(is.alpha2.subordinate * z.min.co.res) |
> monkeyid) + (0 + I(z.co.res * is.alpha2.subordinate) | monkeyid))
>
> BTW, passing that result to lFormula with the
> I(z.co.res * is.alpha2.subordinate) changed to
> I(is.alpha2.subordinate * z.co.res )
> also works.
>
> So as a work around perhaps the solution is to start from the result
> of lFormula on the original formula and make my incremental changes
> to that.
>
> _______________________________________________
> R-sig-mixed-models at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-mixed-models
>
More information about the R-sig-mixed-models
mailing list