Domanda

Ho un frame di dati che si presenta così (semplificate per l'esposizione):

date id value
d1 id1 v1
d2 id1 v2
d1 id2 v3
d2 id2 v4

desidero spezzare questa parte da id, eseguire una regressione rotola su ciascun id (quindi per ogni id ci saranno N regressioni), scegliere la rsquared e montare questo nuovo ad un dataframe. Il mio metodo per fare questo è stato:

roll_reg <- function(df) {
    T <- with(df, min(nlen(xs_ret), nlen(xs_mkt), nlen(smb), nlen(hml), nlen(umd)))
    OFFSET <- 3

    themodels <- as.list(rep(NA, OFFSET))
    #120 days rolling period
    if (T>OFFSET) {
        #the first OFFSET models are na

        for (i in seq(OFFSET+1, T)) {
            idx <- seq(i-OFFSET-1,i)
            themodels[i] <- list(with(df, 
                      lm(xs_ret[idx]~xs_mkt[idx]+smb[idx]+hml[idx]+umd[idx])))

        }

        return(themodels)
    }
    else { return(NA) }
}

models <- dlply(dt_df, "id", roll_reg)

Poi stavo per rimontare il tutto utilizzando

ldply(models, function(x) {summary(x)$r.squared})

Questo non funziona in quanto i modelli è una lista di liste, e x è un elenco di modelli. Tuttavia, se il mio function(x) restituisce un elenco da cat-zione tutte le rsquared in una lista ottengo un errore perché si aspetta ldply function(x) per restituire un risultato atomica. Aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione

Questo codice R viene riprodotto il problema:

library(plyr)

dat = data.frame(date = rep(paste("d", 1:100, sep = ""), length = 100),
             id = rep(paste("id", 1:10, sep = ""), each = 100),
             value = runif(100))

make.lm = function(input) {
  lm1 = lm(value~date, input[1:50,])
  lm2 = lm(value~date, input[1:50,])
  return(list(lm1, lm2))
}

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) summary(x)$r.squared)
# Error in summary(x)$r.squared : $ operator is invalid for atomic vectors

Questo funziona:

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) 
             ldply(x, function(y) 
              return(data.frame(rsq = summary(y)$r.squared))))
coefs$id2 = rep(1:2, each = 2)

> head(coefs)
    id rsq id2
1  id1   1   1
2  id1   1   1
3 id10   1   2
4 id10   1   2
5  id2   1   1
6  id2   1   1

Spero che questo risponde alla tua domanda.

Altri suggerimenti

Non potresti fare

ldply(models, laply, function(x) {summary(x)$r.squared})

In sostanza, poiché la vostra x è un elenco dei modelli, fare un altro l * strati più di questo. Non sono sicuro che il valore di ritorno è giusto, perché non è riproducibile.

Si potrebbe provare rapply che è una versione ricorsiva di lapply. Si potrebbe provare qualcosa di simile

rapply(models, function(model) summary(model)$r.squared)

Questo restituisce solo un vettore di r.squared, e si dovrà ricreare il frame di dati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top