R, lm'deki eksik değerleri nasıl ele alır?


32

Bir B vektörünü bir matris A'daki her bir sütuna karşı germek istiyorum. Bu, eksik veri yoksa önemsizdir, ancak A matrisi eksik değerler içeriyorsa, A'ya karşı regresyonum yalnızca tüm satırları içerecek şekilde sınırlandırılmıştır. değerler var (varsayılan na.omit davranışı). Bu, eksik veri içermeyen sütunlar için hatalı sonuçlar üretir. B matrisi sütununu, A matrisinin ayrı sütunlarına göre gerileyebilirim, ancak yapacaklarım gereken binlerce regresyon var ve bu, oldukça yavaş ve inelegant. Na.exclude fonksiyonu bu durum için tasarlanmış gibi görünüyor, ama ben işi yapamaz. Neyi yanlış yapıyorum burada? Önemli ise, OSX'de R 2.13 kullanılması.

A = matrix(1:20, nrow=10, ncol=2)
B = matrix(1:10, nrow=10, ncol=1)
dim(lm(A~B)$residuals)
# [1] 10 2 (the expected 10 residual values)

# Missing value in first column; now we have 9 residuals
A[1,1] = NA  
dim(lm(A~B)$residuals)
#[1]  9 2 (the expected 9 residuals, given na.omit() is the default)

# Call lm with na.exclude; still have 9 residuals
dim(lm(A~B, na.action=na.exclude)$residuals)
#[1]  9 2 (was hoping to get a 10x2 matrix with a missing value here)

A.ex = na.exclude(A)
dim(lm(A.ex~B)$residuals)
# Throws an error because dim(A.ex)==9,2
#Error in model.frame.default(formula = A.ex ~ B, drop.unused.levels = TRUE) : 
#  variable lengths differ (found for 'B')

1
"Her satırı ayrı ayrı hesaplayabilirim" derken ne demek istiyorsun?
chl

Maalesef "B sütunu matrisini A tek tek sütunlarda A'ya göre gerileyebilirim" anlamına geliyordu; Bunu yansıtacak şekilde düzenlenmiştir.
David Quigley

1
Bir kerede bir lm / regresyon çağrısı, regresyon yapmaya devam etmenin harika bir yolu değildir (regresyonun tanımına göre, bu, her bir tahminin kısmi etkisini, diğerinin durumu ile verilen bir cevap / sonuç üzerinde bulmaktır). değişkenler)
KarthikS

Yanıtlar:


23

Düzenleme: Sorunuzu yanlış anladım. İki yönü var:

a) na.omitve na.excludeher ikisi de hem öngörücülere hem de ölçütlere göre açıkça silme işlemi yapar. Sadece bu çıkarıcı fonksiyonları gibi farklılık residuals()ya fitted()sahip olacak ped kendi çıkışı NAile ihmal durumlarda s na.exclude, böylece giriş değişkenleri aynı uzunlukta bir çıkışa sahip,.

> N    <- 20                               # generate some data
> y1   <- rnorm(N, 175, 7)                 # criterion 1
> y2   <- rnorm(N,  30, 8)                 # criterion 2
> x    <- 0.5*y1 - 0.3*y2 + rnorm(N, 0, 3) # predictor
> y1[c(1, 3,  5)] <- NA                    # some NA values
> y2[c(7, 9, 11)] <- NA                    # some other NA values
> Y    <- cbind(y1, y2)                    # matrix for multivariate regression
> fitO <- lm(Y ~ x, na.action=na.omit)     # fit with na.omit
> dim(residuals(fitO))                     # use extractor function
[1] 14  2

> fitE <- lm(Y ~ x, na.action=na.exclude)  # fit with na.exclude
> dim(residuals(fitE))                     # use extractor function -> = N
[1] 20  2

> dim(fitE$residuals)                      # access residuals directly
[1] 14  2

b) Asıl mesele, na.omitve arasındaki bu farkla na.excludedeğil, her ikisinin de yaptığı gibi, kriter değişkenlerini hesaba katan anlaşılır bir şekilde silinmeyi istemiyor gibisiniz.

> X <- model.matrix(fitE)                  # design matrix
> dim(X)                                   # casewise deletion -> only 14 complete cases
[1] 14  2

X+=(XX)1XXβ^=X+YH=XX+Y^=HYXYDolayısıyla, her kriter için ayrı ayrı regresyon yerleştirmenin bir yolu yoktur. lm()Aşağıdakilerin satırları boyunca bir şeyler yaparak genel giderden kaçınmayı deneyebilirsiniz :

> Xf <- model.matrix(~ x)                    # full design matrix (all cases)
# function: manually calculate coefficients and fitted values for single criterion y
> getFit <- function(y) {
+     idx   <- !is.na(y)                     # throw away NAs
+     Xsvd  <- svd(Xf[idx , ])               # SVD decomposition of X
+     # get X+ but note: there might be better ways
+     Xplus <- tcrossprod(Xsvd$v %*% diag(Xsvd$d^(-2)) %*% t(Xsvd$v), Xf[idx, ])
+     list(coefs=(Xplus %*% y[idx]), yhat=(Xf[idx, ] %*% Xplus %*% y[idx]))
+ }

> res <- apply(Y, 2, getFit)    # get fits for each column of Y
> res$y1$coefs
                   [,1]
(Intercept) 113.9398761
x             0.7601234

> res$y2$coefs
                 [,1]
(Intercept) 91.580505
x           -0.805897

> coefficients(lm(y1 ~ x))      # compare with separate results from lm()
(Intercept)           x 
113.9398761   0.7601234 

> coefficients(lm(y2 ~ x))
(Intercept)           x 
  91.580505   -0.805897

X+HQRYlm()


Bu, na.exclude'in nasıl çalışması gerektiğine dair anlayışım göz önüne alındığında mantıklı geliyor. Bununla birlikte,> X.both = cbind (X1, X2) ve sonra> dim (lm (X.both ~ Y, na.action = na.exclude) $ kalıntı) olarak adlandırırsanız, 97 yerine 94 artık alırsınız ve 97.
David Quigley

Bu bir gelişmedir, ancak artıklara bakarsanız (lm (X.both ~ Y, na.action = na.exclude)), X'in 1. sütunundaki eksik değerler olsa bile, her sütunda altı eksik değer olduğunu görürsünüz. her ikisi de sütun 2'dekilerden farklı örneklerdendir. Bu nedenle, na.Exclude artık matrisin şeklini korur, ancak başlık altında R görünüşte yalnızca X.both'un tüm satırlarında mevcut olan değerlerle geriler. Bunun iyi bir istatistiksel nedeni olabilir, ancak başvurum için bu bir problem.
David Quigley

@David sorunuzu yanlış anladım. Sanırım şimdi noktanızı görüyorum ve cevap vermek için cevabımı değiştirdim.
caracal

5

İki yol düşünebilirim. Bunlardan biri veriyi kullanıp na.excludesonra tekrar veriyi birleştirmek :

A = matrix(1:20, nrow=10, ncol=2)
colnames(A) <- paste("A",1:ncol(A),sep="")

B = matrix(1:10, nrow=10, ncol=1)
colnames(B) <- paste("B",1:ncol(B),sep="")

C <- cbind(A,B)

C[1,1] <- NA
C.ex <- na.exclude(C)

A.ex <- C[,colnames(A)]
B.ex <- C[,colnames(B)]

lm(A.ex~B.ex)

Başka bir yol dataargümanı kullanmak ve bir formül oluşturmaktır.

Cd <- data.frame(C)
fr <- formula(paste("cbind(",paste(colnames(A),collapse=","),")~",paste(colnames(B),collapse="+"),sep=""))

lm(fr,data=Cd)

Cd[1,1] <-NA

lm(fr,data=Cd,na.action=na.exclude)

Çok fazla regresyon yapıyorsanız, daha az arka plan büyüsü yapıldığından ilk yol daha hızlı olmalıdır. Her ne kadar sadece katsayılara ve artıklara ihtiyacınız varsa, kullanmanızı öneririm lsfit, hangisi daha hızlı lm. İkinci yol biraz daha hoş, ama dizüstü bilgisayarımda ortaya çıkan regresyonun özetini yapmaya çalışmak bir hata veriyor. Bunun bir hata olup olmadığını görmeye çalışacağım.


Teşekkürler, ama kodunuzdaki lm (A.ex ~ B.ex) A1'e (9) doğru 9, A2'ye (istenmeyen) 9 puan alır. Hem B1 hem de A2 için 10 ölçüm noktası vardır; B1'in A2'ye karşı regresyonunda bir nokta atıyorum çünkü karşılık gelen A1'de eksik. Eğer bu sadece işe yararsa, bunu kabul edebilirim, ama R'yi yapmaya çalıştığım şey bu değil.
David Quigley

@David, oh, sanırım sorununuzu yanlış anladım. Düzeltmeyi daha sonra gönderirim.
mpiktas

1

Aşağıdaki örnek, NA'ların orijinal veri çerçevesinin kalıntı ve tahmin vektörlerine yerleştirilmesi gerektiğini belirtmek için lm () 'deki ("na.action = na.exclude" seçeneğini kullanarak) orijinal veri çerçevesine uyan tahminlerin ve kalıntıların nasıl yapıldığını gösterir. Ayrıca, tahminlerin sadece hem açıklayıcı hem de bağımlı değişkenlerin tamamlanmış gözlemleri (yani, kesinlikle örneklem içi tahminler) veya açıklayıcı değişkenlerin tamamlandığı gözlemleri ve dolayısıyla Xb tahmininin mümkün olduğu gözlemleri içermesi gerektiğini belirtmeyi de göstermektedir. yani, tam açıklayıcı değişkenleri olan ancak bağımlı değişkeni olmayan gözlemler için örneklem dışı tahmin dahil).

Tahmini ve artık değişkenleri orijinal veri kümesine eklemek için cbind kullanıyorum.

## Set up data with a linear model
N <- 10
NXmissing <- 2 
X <- runif(N, 0, 10)
Y <- 6 + 2*X + rnorm(N, 0, 1)
## Put in missing values (missing X, missing Y, missing both)
X[ sample(1:N , NXmissing) ] <- NA
Y[ sample(which(is.na(X)), 1)]  <- NA
Y[ sample(which(!is.na(X)), 1)]  <- NA
(my.df <- data.frame(X,Y))

## Run the regression with na.action specified to na.exclude
## This puts NA's in the residual and prediction vectors
my.lm  <- lm( Y ~ X, na.action=na.exclude, data=my.df)

## Predict outcome for observations with complete both explanatory and
## outcome variables, i.e. observations included in the regression
my.predict.insample  <- predict(my.lm)

## Predict outcome for observations with complete explanatory
## variables.  The newdata= option specifies the dataset on which
## to apply the coefficients
my.predict.inandout  <- predict(my.lm,newdata=my.df)

## Predict residuals 
my.residuals  <- residuals(my.lm)

## Make sure that it binds correctly
(my.new.df  <- cbind(my.df,my.predict.insample,my.predict.inandout,my.residuals))

## or in one fell swoop

(my.new.df  <- cbind(my.df,yhat=predict(my.lm),yhato=predict(my.lm,newdata=my.df),uhat=residuals(my.lm)))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.