J'espère obtenir de l'aide sur le problème suivant dans R.
J'ai 4 variables, numéro d'entreprise
, ventes
, taille
, date
, pour près de 4 000 entreprises.
Je souhaite exécuter cette régression:
lm (size ~ sales)
, tout en ajoutant 100 entreprises à la fois à partir des 4000.
Ainsi, la première régression aura 100 firmes, la seconde en aura 200, la troisième en aura 300 ... jusqu'à atteindre la dernière régression qui inclut toutes les firmes (4000).
La deuxième tâche, c'est que je veux enregistrer le coefficient bêta de chaque régression (c'est-à-dire chaque régression après avoir ajouté 100 entreprises supplémentaires), puis tracer le bêta sur Y et le nombre d'entreprises sur x (de 100 à 4000) pour observer comment la version bêta change lors de l'ajout d'entreprises.
Ai-je besoin d'une sorte de boucle pour les régressions, d'une boucle pour sauvegarder les bêtas et d'une boucle pour le traçage? Merci d'avoir lu
3 Réponses :
Voici un exemple minimal pour vous en utilisant le jeu de données mtcars
. J'ai construit une régression en ajoutant une ligne à la fois. Je préalloue un vecteur de résultats vers la droite puis je parcours les lignes et je stocke les résultats du coefficient.
results <- vector(length = nrow(mtcars)) for (j in 1:nrow(mtcars)){ results[j] <- coef(lm(mpg ~ hp, data = mtcars[1:j, ]))[2] } plot(x = 1:nrow(mtcars), y = results, type = "p")
Créé le 07/04/2019 par le package reprex (v0.2.1)
Pensez à diviser votre ensemble de données par entreprises, puis à exécuter de manière itérative lm
en utilisant une séquence seq (1, 4000, par = 100)
pour sous-ensemble diviser la liste des cadres de données:
# FUNCTION TO CALL lm() AND EXTRACT RESULTS lm_results <- function(n, df, yy, mm) { model <- lm(sales ~ size, data = df) res <- summary(model) p <- res$fstatistic c(year = yy, month = mm, num_of_firms = n, sales = res$coefficients[2,1], std_err = res$coefficients[2,2], t_stat = res$coefficients[2,3], t_pvalue = res$coefficients[2,4], r_sq = res$r.squared, adj_r_sq = res$adj.r.squared, f_stat = p[['value']], f_pvalue = unname(pf(p[1], p[2], p[3], lower.tail=FALSE)) ) } # BUILD A LIST OF MONTHLY MATRICES BY YEAR firms_mat_list <- by(df, df$yy, function(sub_year){ # BUILD A LIST OF FIRM MATRICES BY MONTH month_mat_list <- by(sub_year, sub_year$mm, function(sub_month){ firms_df_list <- split(sub_month, sub_month$firm) # BUILD MATRIX RESULTS WHERE ROWS ARE MODEL RUNS AND COLS ARE RESULT ESTIMATES mat_results <- t(sapply(seq(1, 4000, by=100), function(i) { # COMBINE FIRM SUBSETS BY RANGE curr_df <- do.call(rbind, firms_df_list[1:i]) # CALL MODEL AND RETRIEVE RESULTS lm_results(i, curr_df, curr_df$yy[1], curr_df$mm[1]) })) }) do.call(rbind, month_mat_list) }) firms_matrix <- do.call(rbind, firms_mat_list) firms_matrix
Pour tenir compte de la ventilation par année et par mois, considérez by
(similaire à split
+ lapply
) sous-ensemble par année, puis par mois avec split
interne (similaire au processus ci-dessus) où chaque itération exécute le modèle nécessaire. Ensuite, liez les matrices à chaque niveau de mois et d'année pour une grande matrice finale. Remarque: lm_results
reçoit désormais deux paramètres supplémentaires pour les colonnes de la matrice de l'indicateur mois et année.
# BUILD A LIST OF DATA FRAMES (SIZE = 4,000) firms_df_list <- split(df, df$firm_id) # FUNCTION TO CALL lm() AND EXTRACT RESULTS lm_results <- function(n, df) { model <- lm(sales ~ size, data = df) res <- summary(model) p <- res$fstatistic c(num_of_firms = n, sales = res$coefficients[2,1], std_err = res$coefficients[2,2], t_stat = res$coefficients[2,3], t_pvalue = res$coefficients[2,4], r_sq = res$r.squared, adj_r_sq = res$adj.r.squared, f_stat = p[['value']], f_pvalue = unname(pf(p[1], p[2], p[3], lower.tail=FALSE)) ) } # BUILD MATRIX RESULTS WHERE ROWS ARE MODEL RUNS AND COLS ARE RESULT ESTIMATES mat_results <- t(sapply(seq(1, 4000, by=100), function(i) { # COMBINE FIRM SUBSETS BY RANGE curr_df <- do.call(rbind, firms_df_list[1:i]) # CALL MODEL AND RETRIEVE RESULTS lm_results(i, curr_df) })) # PLOT ALL SALES BETAS AND NUMBER OF FIRMS plot(mat_results[,"num_of_firms"], mat_results[,"sales"], type="b", col="blue", lwd=1, pch=16, xlab="Number of Firms", ylab="Sales Estimate")
Merci, cela a fonctionné, cependant, chaque entreprise est observée sur une base mensuelle (ce que j'ai manqué de mentionner dans ma question initiale), j'ai donc une colonne pendant des années (certaines observées de 2000 à 2016, d'autres sur moins de temps) et un colonne pour le mois qui correspond à chaque année. en tenant compte de l'année et des mois, je suppose que cela affectera la sortie de la régression, pouvez-vous s'il vous plaît conseiller sur la façon de prendre en compte les années et les mois pour chaque entreprise lors de l'exécution de model <- lm (sales ~ size, data = df) code >? Ai-je besoin d'une sorte de boucle sur des mois et des années?
Hou la la! Je pensais te perdre de l'autre côté d'Internet! Parfois, nous obtenons des OP qui disparaissent. Mais qu'entendez-vous exactement par compte pendant des mois et des années. Voulez-vous diviser davantage la taille des entreprises par année / mois ou les inclure dans la régression?
Merci!! Ce que je voulais dire, c'est que chaque entreprise de l'entreprise 1 à l'entreprise 4000 est observée mensuellement au fil des ans, variable mm de 1 à 12 et aa de 2005 à 2016. Mes variables sont: vente de taille entreprise mm aa
Fondamentalement, Je veux exécuter la régression pour inclure tous les mois de chaque année, puis ajouter 100 entreprises à la fois, c'est-à-dire couvrant tous les mois de toutes les années et les 4 000 entreprises. Le code que vous avez fourni, je pense, prend toutes les observations à la fois ... nous devons probablement reproduire la régression sur des mois et des années pour tenir compte du temps? Merci encore une fois, au plaisir.
Voir la répartition des mises à jour par année et par mois avec by
avant les exécutions de modélisation avec split
.
La deuxième tâche, c'est que je veux enregistrer le coefficient bêta de chaque régression (c'est-à-dire chaque régression après avoir ajouté 100 entreprises supplémentaires), puis tracer le bêta sur Y et le nombre d'entreprises sur x (de 100 à 4000) pour observer comment la version bêta change lors de l'ajout d'entreprises.
Vous pouvez utiliser mon package
rollRegres
. C'est presque identique à l'exemple de cette vignette :microbenchmark::microbenchmark( roll_regres(y ~ X, do_downdates = FALSE, width = 100L)) #R Unit: microseconds #R expr min lq mean median uq max neval #R roll_regres(y ~ X, do_downdates = FALSE, width = 100L) 740 750 771 763 772 1090 100Il vous donne toute la valeur 40000 - 99 mais il le fait rapidement donc vous ne vous soucierez probablement pas du calcul supplémentaire
set.seed(65731482) ngrp <- 40L n_per_g <- 100L # create group variable grp <- c(sapply(1:ngrp, rep, times = n_per_g)) n <- n_per_g * ngrp p <- 1L X <- matrix(rnorm(p * n), n, p) y <- drop(X %*% 1.5) + rnorm(n) library(rollRegres) out <- roll_regres(y ~ X, do_downdates = FALSE, width = 100L) beta <- out$coefs # check result tail(out$coefs, 2) #R (Intercept) X #R 3999 -0.00552 1.51 #R 4000 -0.00571 1.51 coef(lm(y ~ X)) #R (Intercept) X #R -0.00571 1.51405 # plot plot(out$coefs[, 2], xlab = "Time", ylab = "slope", type = "l")