r plyr lm predict

r - shiny using html



usando predicción con una lista de objetos lm() (6)

Aquí está mi intento:

predNaughty <- ddply(newData, "state", transform, value=predict(modelList[[paste(piece$state[1])]], newdata=piece)) head(predNaughty) # year state value # 1 50 50 5176.326 # 2 51 50 5274.907 # 3 52 50 5373.487 # 4 53 50 5472.068 # 5 54 50 5570.649 # 6 55 50 5669.229 predDiggsApproved <- ddply(newData, "state", function(x) transform(x, value=predict(modelList[[paste(x$state[1])]], newdata=x))) head(predDiggsApproved) # year state value # 1 50 50 5176.326 # 2 51 50 5274.907 # 3 52 50 5373.487 # 4 53 50 5472.068 # 5 54 50 5570.649 # 6 55 50 5669.229

Edición larga de JD

Me inspiré lo suficiente como para elaborar una opción adply() :

pred3 <- adply(newData, 1, function(x) predict(modelList[[paste(x$state)]], newdata=x)) head(pred3) # year state 1 # 1 50 50 5176.326 # 2 51 50 5274.907 # 3 52 50 5373.487 # 4 53 50 5472.068 # 5 54 50 5570.649 # 6 55 50 5669.229

Tengo datos con los que regularmente ejecuto regresiones. Cada "fragmento" de datos se ajusta a una regresión diferente. Cada estado, por ejemplo, puede tener una función diferente que explica el valor dependiente. Esto parece un problema típico de tipo "dividir-aplicar-combinar", entonces estoy usando el paquete plyr. Puedo crear fácilmente una lista de objetos lm() que funciona bien. Sin embargo, no puedo comprender cómo uso esos objetos más adelante para predecir valores en un cuadro de datos separado.

Aquí hay un ejemplo totalmente artificial que ilustra lo que estoy tratando de hacer:

# setting up some fake data set.seed(1) funct <- function(myState, myYear){ rnorm(1, 100, 500) + myState + (100 * myYear) } state <- 50:60 year <- 10:40 myData <- expand.grid( year, state) names(myData) <- c("year","state") myData$value <- apply(myData, 1, function(x) funct(x[2], x[1])) ## ok, done with the fake data generation. require(plyr) modelList <- dlply(myData, "state", function(x) lm(value ~ year, data=x)) ## if you want to see the summaries of the lm() do this: # lapply(modelList, summary) state <- 50:60 year <- 50:60 newData <- expand.grid( year, state) names(newData) <- c("year","state") ## now how do I predict the values for newData$value # using the regressions in modelList?

Entonces, ¿cómo uso los objetos lm() contenidos en modelList para predecir valores usando el año y los valores independientes del estado de newData ?


Lo que está mal con

lapply(modelList, predict, newData)

?

EDITAR:

Gracias por explicar lo que está mal con eso. Qué tal si:

newData <- data.frame(year) ldply(modelList, function(model) { data.frame(newData, predict=predict(model, newData)) })

Iterar sobre los modelos y aplicar los nuevos datos (que es el mismo para cada estado, ya que acaba de hacer un expand.grid para crearlo).

EDIT 2:

Si newData no tiene los mismos valores por year para cada state que en el ejemplo, se puede usar un enfoque más general. Tenga en cuenta que esto utiliza la definición original de newData , no la de la primera edición.

ldply(state, function(s) { nd <- newData[newData$state==s,] data.frame(nd, predict=predict(modelList[[as.character(s)]], nd)) })

Primeras 15 líneas de esta salida:

year state predict 1 50 50 5176.326 2 51 50 5274.907 3 52 50 5373.487 4 53 50 5472.068 5 54 50 5570.649 6 55 50 5669.229 7 56 50 5767.810 8 57 50 5866.390 9 58 50 5964.971 10 59 50 6063.551 11 60 50 6162.132 12 50 51 5514.825 13 51 51 5626.160 14 52 51 5737.496 15 53 51 5848.832


Supongo que la parte difícil es hacer coincidir cada estado en newData con el modelo correspondiente.

¿Algo así tal vez?

predList <- dlply(newData, "state", function(x) { predict(modelList[[as.character(min(x$state))]], x) })

Aquí utilicé una forma "pirata" de extraer el modelo de estado correspondiente: as.character(min(x$state))

... probablemente hay una mejor manera?

Salida:

> predList[1:2] $`50` 1 2 3 4 5 6 7 8 9 10 11 5176.326 5274.907 5373.487 5472.068 5570.649 5669.229 5767.810 5866.390 5964.971 6063.551 6162.132 $`51` 12 13 14 15 16 17 18 19 20 21 22 5514.825 5626.160 5737.496 5848.832 5960.167 6071.503 6182.838 6294.174 6405.510 6516.845 6628.181

O, si quieres un data.frame como salida:

predData <- ddply(newData, "state", function(x) { y <-predict(modelList[[as.character(min(x$state))]], x) data.frame(id=names(y), value=c(y)) })

Salida:

head(predData) state id value 1 50 1 5176.326 2 50 2 5274.907 3 50 3 5373.487 4 50 4 5472.068 5 50 5 5570.649 6 50 6 5669.229


Tal vez me esté perdiendo algo, pero creo que lmList es la herramienta ideal aquí,

library(nlme) ll = lmList(value ~ year | state, data=myData) predict(ll, newData) ## Or, to show that it produces the same results as the other proposed methods... newData[["value"]] <- predict(ll, newData) head(newData) # year state value # 1 50 50 5176.326 # 2 51 50 5274.907 # 3 52 50 5373.487 # 4 53 50 5472.068 # 5 54 50 5570.649 # 6 55 50 5669.229


Una solución con solo la base R. El formato de la salida es diferente, pero todos los valores están ahí.

models <- lapply(split(myData, myData$state), ''lm'', formula = value ~ year) pred4 <- mapply(''predict'', models, split(newData, newData$state))


mdply usar mdply para suministrar tanto el modelo como los datos a cada llamada de función:

dataList <- dlply(newData, "state") preds <- mdply(cbind(mod = modelList, df = dataList), function(mod, df) { mutate(df, pred = predict(mod, newdata = df)) })