Perché sta usando l’aggiornamento su un lm all’interno di un gruppo data.table che perde i dati del modello?

Ok, questo è strano. Sospetto che si tratti di un bug all’interno di data.table , ma sarebbe utile se qualcuno potesse spiegare perché questo sta accadendo – cosa sta facendo esattamente l’ update ?

Sto usando il trucco list(list()) all’interno di data.table per memorizzare i modelli adattati. Quando si crea una sequenza di oggetti lm ciascuno per diversi raggruppamenti e quindi si update tali modelli, i dati del modello per tutti i modelli diventano quelli dell’ultimo raggruppamento. Sembra che un riferimento si aggiri da qualche parte dove dovrebbe essere stata creata una copia, ma non riesco a trovare dove e non riesco a riprodurlo al di fuori di lm e ad update .

Esempio concreto:

Iniziando con i dati dell’iride, prima di tutto fai in modo che le tre specie abbiano diverse dimensioni del campione, quindi adattare un modello lm a ciascuna specie, aggiorna i modelli:

 set.seed(3) DT = data.table(iris) DT = DT[rnorm(150) < 0.9] fit = DT[, list(list(lm(Sepal.Length ~ Sepal.Width + Petal.Length))), by = Species] fit2 = fit[, list(list(update(V1[[1]], ~.-Sepal.Length))), by = Species] 

La tabella dei dati originale ha numeri diversi per ogni specie

 DT[,.N, by = Species] # Species N # 1: setosa 41 # 2: versicolor 39 # 3: virginica 42 

E il primo adattamento conferma questo:

 fit[, nobs(V1[[1]]), by = Species] # Species V1 # 1: setosa 41 # 2: versicolor 39 # 3: virginica 42 

Ma il secondo aggiornamento aggiornato sta mostrando 42 per tutti i modelli

 fit2[, nobs(V1[[1]]), by = Species] # Species V1 # 1: setosa 42 # 2: versicolor 42 # 3: virginica 42 

Possiamo anche esaminare l’attributo del modello che contiene i dati usati per l’adattamento e vedere che tutti i modelli stanno effettivamente utilizzando i dati dei gruppi finali. La domanda è: com’è successo?

 head(fit$V1[[1]]$model) # Sepal.Length Sepal.Width Petal.Length # 1 5.1 3.5 1.4 # 2 4.9 3.0 1.4 # 3 4.7 3.2 1.3 # 4 4.6 3.1 1.5 # 5 5.0 3.6 1.4 # 6 5.4 3.9 1.7 head(fit$V1[[3]]$model) # Sepal.Length Sepal.Width Petal.Length # 1 6.3 3.3 6.0 # 2 5.8 2.7 5.1 # 3 6.3 2.9 5.6 # 4 7.6 3.0 6.6 # 5 4.9 2.5 4.5 # 6 7.3 2.9 6.3 head(fit2$V1[[1]]$model) # Sepal.Length Sepal.Width Petal.Length # 1 6.3 3.3 6.0 # 2 5.8 2.7 5.1 # 3 6.3 2.9 5.6 # 4 7.6 3.0 6.6 # 5 4.9 2.5 4.5 # 6 7.3 2.9 6.3 head(fit2$V1[[3]]$model) # Sepal.Length Sepal.Width Petal.Length # 1 6.3 3.3 6.0 # 2 5.8 2.7 5.1 # 3 6.3 2.9 5.6 # 4 7.6 3.0 6.6 # 5 4.9 2.5 4.5 # 6 7.3 2.9 6.3