Skip to content

define subset argument for function lm as variable?

14 messages · Bert Gunter, Rainer M Krug, Joshua Wiley +2 more

#
Hi

I want to do a series of linear models, and would like to define the input arguments for lm() as 
variables. I managed easily to define the formula arguments in a variable, but I also would like to 
have the "subset" in a variable. My reasoning is, that I have the subset in the results object.

So I wiould like to add a line like:

subs <- dead==FALSE & recTreat==FALSE

which obviously does not work as the expression is evaluated immediately. Is is it possible to do 
what I want to do here, or do I have to go back to use

dat <- subset(dat, dead==FALSE & recTreat==FALSE)

?



dat <- loadSPECIES(SPECIES)
feff <- height~pHarv*year               # fixed effect in the model
reff <- ~year|plant                     # random effect in the model, where year is the
dat.lme <- lme(
              fixed = feff,                           # fixed effect in the model
              data  = dat,
              random = reff,                          # random effect in the model
              correlation = corAR1(form=~year|plant), #
              subset = dead==FALSE & recTreat==FALSE, #
              na.action = na.omit
              )
dat.lm <- lm(
             formula =  feff,              # fixed effect in the model
             data = dat,
             subset = dead==FALSE & recTreat==FALSE,
             na.action = na.omit
             )

Thanks,

Rainer
#
Hi Rainer,

You could try:

subs <- expression(dead==FALSE & recTreat==FALSE)

lme(formula, subset = eval(subs))

Not tested, but something along those lines should work.

Cheers,

Josh
On Tue, Aug 21, 2012 at 7:44 AM, Rainer M Krug <r.m.krug at gmail.com> wrote:

  
    
#
?? I do not groc what you mean. ... subset == subs would work fine in
your lm call. So unless someone else does get it, you may need to
elaborate.

In general, ?substitute, ?bquote, and ?quote are useful to avoid
immediate evaluation of calls, but I don't know if that's relevant to
what you want here.

-- Bert
On Tue, Aug 21, 2012 at 7:44 AM, Rainer M Krug <r.m.krug at gmail.com> wrote:

  
    
#
On 21/08/12 16:57, Bert Gunter wrote:
OK - here is an example:

dat <- data.frame(
          ctl = c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14),
          trt = c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69),
          group = gl(2,10,20, labels=c("Ctl","Trt")),
          weight = c(ctl, trt)
          )
lm(weight ~ group, data=dat, subset=trt>0)

subst <- trt>0 ### here I get the obvious error: Error: object 'trt' not found

# I want to use:

lm(weight ~ group, data=dat, subset=subst)
Looks promising from the help, but I don't get it to work.

Rainer

  
    
#
Hi Rainer,
I got an error while replicating your data.frame construction.

But this worked for me

ctl = c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt = c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
dat <- data.frame( group = gl(2,10,20, labels=c("Ctl","Trt")),
         weight = c(ctl, trt)
         )
lm(weight ~ group, data=dat, subset=trt>0)

Cheers

Am 21.08.2012 17:11, schrieb Rainer M Krug:

  
    
#
On 21/08/12 17:35, Eik Vettorazzi wrote:
Sorry  - to much garbage in my workspace left.

Just add:

rm(ctl)
rm(trt)

after the definition
this obviously works, but I would like to have:

subst <- trt>0
lm(weight ~ group, data=dat, subset=subst)

Sorry about this,

Rainer

  
    
#
What is wrong with what I suggested initially?

subst <- expression(trt > 0)
lm(weight ~ group, data=dat, subset=eval(subst))


??
On Tue, Aug 21, 2012 at 8:41 AM, Rainer M Krug <r.m.krug at gmail.com> wrote:

  
    
#
On 21/08/12 17:54, Joshua Wiley wrote:
That it does not work?

ctl = c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt = c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
dat <- data.frame( group = gl(2,10,20, labels=c("Ctl","Trt")),
          weight = c(ctl, trt)
          )
rm(ctl)
rm(trt)
subst <- expression(trt > 0)
lm(weight ~ group, data=dat, subset=eval(subst))
# output: Error in eval(expr, envir, enclos) : object 'trt' not found


and

lm(weight ~ group, data=dat, subset=subst)
# output: Error in xj[i] : invalid subscript type 'expression'
 >

also does not work.

Rainer

  
    
#
Josh's solution should be fine.

just one more note,
trt>0 may not work as intended since trt is a factor in your example.
Just check
subset(dat,trt>0)
wich is just 'dat'.



Am 21.08.2012 17:41, schrieb Rainer M Krug:

  
    
#
Sorry - it is working as suggested by Joshua.

Thanks a lot and sorry for the horrible confusion and examples,

Rainer
On 21/08/12 18:12, Rainer M Krug wrote:
7 days later
#
Le mardi 21 ao?t 2012 ? 07:51 -0700, Joshua Wiley a ?crit :
Out of curiosity, why isn't "subset" (and "weights", which is very
similar in that regard) evaluated in the "data" environment, just like
the formula? Is this for historical reasons, or are there drawbacks to
such a feature?

It seems very common to pass a data frame via the "data" argument, and
use variables from it for subsetting and/or weighting.


Regards
#
On Wed, Aug 29, 2012 at 3:56 AM, Milan Bouchet-Valat <nalimilan at club.fr> wrote:
I am not sure about weights offhand, but subset is evaluated in the
data environment----that is why that solution works.  The original
question was how to setup the expression as an object that was passed
to subset.  The trick is to avoid having the logical expression
evaluated when the object is created, which I avoided by using
expression, and then in lme() forcing the evaluation of the object.

  
    
#
Le mercredi 29 ao?t 2012 ? 04:01 -0700, Joshua Wiley a ?crit :
OK, my phrasing was not really correct. What I meant (and what triggered
the OP question) was : why doesn't the "subset" argument behave the same
in lm() and in subset.data.frame()? Is there any advantage to evaluating
the argument at the object creation?

AFAICS, subset.data.frame() merely uses this trick:
e <- substitute(subset)
r <- eval(e, x, parent.frame())


I'm probably missing something... ;-)
#
Le mercredi 29 ao?t 2012 ? 14:26 +0200, Milan Bouchet-Valat a ?crit :
Nevermind, forget this silly question. This works exactly as I describe
it, it's just that I did not get the OP's problem right, and for an
unexplained reason in my testing this did not work. But now I realize,
as you said, the problem is just that the OP wanted to store the subset
in an object first.

Sorry for the noise - at least I learned I can specify "weights" the
easy way... ;-)