简体   繁体   中英

Looping over dependent variable in a mixed model

I am trying to loop over multiple variables in a mixed model (using the rptGaussian function from the rptR package) but I am unable to do it despite several efforts. I am trying the following code. I use the following code without a loop and it works fine:

(rptGaussian(Arg ~  (1|class)+(1|kit)+(1|sex),
    grname=c("class","kit","sex","Fixed"),
    data=ggm2, nboot=10, npermut=10, adjusted=FALSE)

However, when I try to loop more variables I get the error

Error in terms.default(formula) : no terms component nor attribute

I am trying the following code for the loop.

varlist<-c("var1", "var2")

blups.models <- lapply(varlist, function(x) {
  rptGaussian(substitute(i ~  (1|class)+(1|kit)+(1|sex), 
    list(i = as.name(x))), 
      grname=c("class","kit","lab","Fixed"),
      data=ggm2, nboot=10, npermut=10, adjusted=FALSE)
})

Here is a dummy data table:

sex class   kit var1    var2    var3    var4
Female  A   Cont    10.79730768 10  20  18
Female  A   Exp 11.2474347  17  1   17
Female  A   Cont    11.64820939 10  5   17
Female  A   Exp 15.62800413 20  8   4
Female  B   Cont    12.41705885 5   16  8
Female  B   Exp 12.80249244 9   10  1
Female  B   Cont    10.76949177 6   13  2
Female  B   Exp 14.71370141 7   12  11
Male    A   Cont    8.931529823 8   3   6
Male    A   Exp 10.46899683 3   12  13
Male    A   Cont    8.363257621 3   13  17
Male    A   Exp 8.753117911 10  16  10
Male    B   Cont    9.110946315 9   13  4
Male    B   Exp 9.595131886 18  10  17
Male    B   Cont    9.454670188 1   10  11
Male    B   Exp 10.59379123 11  1   3

In general this kind of looping is easier (IMO) with string-based solutions, especially the reformulate() wrapper function, than with substitute() .

I used read.table(header=TRUE,text="...") to read the data above and this slightly modified code for the single model:

library(rptR)
r1 <- rptGaussian(var1 ~  (1|class)+(1|kit)+(1|sex),
    grname=c("class","kit","sex","Fixed"),
    data=ggm2, nboot=10, npermut=10, adjusted=FALSE)

For multiple models:

varlist <- c("var1", "var2")

Make list of formulas:

formulas <- lapply(varlist,
          reformulate,
          termlabels="(1|class)+(1|kit)+(1|sex)")

Apply rptGaussian to formulas:

blups.models <- lapply(formulas, 
      rptGaussian,
      grname=c("class","kit","sex","Fixed"),
      data=ggm2, nboot=10, npermut=10, adjusted=FALSE)

If you want to collapse the results to a nice form, you have to figure out how to extract the results from a single fit into a data frame or similar structure. In this case the result is a rpt object and methods(class="rpt") tells you that there are only print , plot , and summary methods, but the summary() method returns an object that has lots of potentially useful bits. Here's an example:

## extract estimates and standard errors of estimates as a 1-row data frame
sumfun <- function(x) {
    ss <- summary(x)
    se.names <- paste(rownames(ss$se),"se",sep=".")
    cbind(ss$R,setNames(as.data.frame(t(ss$se)),se.names))
}

A possibly-better alternative would be to return data.frame(term=names(ss$R),rpt=unlist(ss$R),se=ss$se) (a 3-column by n-row data frame) instead.

I'm going to use dplyr::bind_rows() because it's handy, but you could use base-R tools ( do.call(rbind(...)) ) instead if you prefer.

names(blups.models) <- varlist
dplyr::bind_rows(lapply(blups.models,sumfun),
                 .id="var")

   var class       kit        sex Fixed   class.se    kit.se    sex.se Fixed.se
1 var1     0 0.1444659 0.65887365     0 0.04992624 0.2136589 0.2954982        0
2 var2     0 0.3322780 0.01734343     0 0.01981748 0.2243989 0.1158878        0

Are you sure it makes sense to do repeatability scores across sexes and other categories with small numbers of levels?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM