2011-06-08 178 views
5

我想對R中的正態和雙重對數圖中的數據進行線性迴歸。R中的線性迴歸(正態和對數數據)

對於正常數據數據集可能是follwing:

lin <- data.frame(x = c(0:6), y = c(0.3, 0.1, 0.9, 3.1, 5, 4.9, 6.2)) 
plot (lin$x, lin$y) 

有我想要計算畫一條線用於線性迴歸只的數據點2,3和4

對於雙對數的數據數據集可能如下:

data = data.frame(
    x=c(1:15), 
    y=c(
     1.000, 0.742, 0.623, 0.550, 0.500, 0.462, 0.433, 
     0.051, 0.043, 0.037, 0.032, 0.028, 0.025, 0.022, 0.020 
    ) 
    ) 
plot (data$x, data$y, log="xy") 

這裏我想繪製數據集1:7和8:15的迴歸線。

何我可以計算斜率y偏移量 ALS以及用於擬合(R^2p值)參數?

正常和對數數據如何處理?

感謝您的幫助,

斯文

回答

9

在R,線性最小二乘模型通過lm()函數擬合。使用公式界面,我們可以使用subset參數來選擇用於貼合實際的模型中的數據點,例如:

lin <- data.frame(x = c(0:6), y = c(0.3, 0.1, 0.9, 3.1, 5, 4.9, 6.2)) 
linm <- lm(y ~ x, data = lin, subset = 2:4) 

捐贈:

R> linm 

Call: 
lm(formula = y ~ x, data = lin, subset = 2:4) 

Coefficients: 
(Intercept)   x 
    -1.633  1.500 

R> fitted(linm) 
     2   3   4 
-0.1333333 1.3666667 2.8666667 

至於爲雙數,你有兩個我猜想的選擇; i)如上所述估計兩個獨立的模型,或ii)通過ANCOVA進行估計。對數轉換使用log()在公式中完成。

通過兩個獨立的型號:

logm1 <- lm(log(y) ~ log(x), data = dat, subset = 1:7) 
logm2 <- lm(log(y) ~ log(x), data = dat, subset = 8:15) 

或通過協方差分析,我們需要變

dat <- transform(dat, ind = factor(1:15 <= 7)) 
logm3 <- lm(log(y) ~ log(x) * ind, data = dat) 

你可能會問,如果這兩種方法是等效的指標?那麼他們是,我們可以通過模型係數來展示這一點。

R> coef(logm1) 
    (Intercept)  log(x) 
-0.0001487042 -0.4305802355 
R> coef(logm2) 
(Intercept)  log(x) 
    0.1428293 -1.4966954 

所以這兩個斜坡是-0。4306和-1.4967的單獨型號。 ANCOVA模型的係數爲:

R> coef(logm3) 
    (Intercept)   log(x)  indTRUE log(x):indTRUE 
    0.1428293  -1.4966954  -0.1429780  1.0661152 

我們如何調和兩者?那麼我設置的方式ind,logm3被參數化以便更直接地給出從logm2估計的值; logm2logm3的截距與log(x)的係數相同。要獲得相當於係數 的logm1的價值,我們需要做的操作,第一截距:

R> coefs[1] + coefs[3] 
    (Intercept) 
-0.0001487042 

其中用於indTRUE係數超過組平均在第1組的平均值之差2.而對於斜率:

R> coefs[2] + coefs[4] 
    log(x) 
-0.4305802 

這是相同的,我們得到用於logm1和基於所述斜率爲組2(coefs[2])通過用於組1(coefs[4])中斜率的差別修改。

至於繪圖,一個簡單的方法是通過abline()簡單模型。例如。對於正常的數據例如:

plot(y ~ x, data = lin) 
abline(linm) 

對於日誌數據,我們可能需要多一點創意,這裏的一般解決方法是預測在數據的範圍,並繪製預測:

pdat <- with(dat, data.frame(x = seq(from = head(x, 1), to = tail(x,1), 
            by = 0.1)) 
pdat <- transform(pdat, yhat = c(predict(logm1, pdat[1:70,, drop = FALSE]), 
           predict(logm2, pdat[71:141,, drop = FALSE]))) 

這可以繪製在原有規模,乘冪yhat

plot(y ~ x, data = dat) 
lines(exp(yhat) ~ x, dat = pdat, subset = 1:70, col = "red") 
lines(exp(yhat) ~ x, dat = pdat, subset = 71:141, col = "blue") 

或對數刻度:

plot(log(y) ~ log(x), data = dat) 
lines(yhat ~ log(x), dat = pdat, subset = 1:70, col = "red") 
lines(yhat ~ log(x), dat = pdat, subset = 71:141, col = "blue") 

例如...

這是一般的解決方案非常適用於更復雜的模型ANCOVA過。在這裏,我像以前一樣創建一個新的PDAT和指示劑添加

pdat <- with(dat, data.frame(x = seq(from = head(x, 1), to = tail(x,1), 
            by = 0.1)[1:140], 
          ind = factor(rep(c(TRUE, FALSE), each = 70)))) 
pdat <- transform(pdat, yhat = predict(logm3, pdat)) 

注意我們是如何得到所有我們從單一的呼叫predict()因爲使用ANCOVA的希望,以適應logm3預測。我們現在可以像以前一樣繪製:

plot(y ~ x, data = dat) 
lines(exp(yhat) ~ x, dat = pdat, subset = 1:70, col = "red") 
lines(exp(yhat) ~ x, dat = pdat, subset = 71:141, col = "blue") 
+0

我該如何獲得一個名爲num的單個數字? 'str(coef(daten_fit))'給出: '命名的數字0.8 - attr(*,「names」)= chr「x」',但它是否可能問coef以名稱「x 」。我嘗試了不同的想法,比如'coeff(daten_fit)$ x'或'coeff(daten_fit)[1]'或'attr(coeff(daten_fit),「x」)',但是沒有任何工作。是不可能通過名字得到價值? – 2011-06-08 17:59:08

+1

@Sven它是一個命名的數字向量。請注意,它是'coef()'與一個「f」而不是'coeff()'與兩個。 '我的答案中的'logm2'對象爲''coef(logm2)[「(Intercept)」]和'coef(logm2)[「log(x)」]你不能在原子向量(一種基本類型的向量)上使用'$',它只能用於列表(以及當然是列表的數據幀)。 – 2011-06-08 18:10:25

2
#Split the data into two groups 
data1 <- data[1:7, ] 
data2 <- data[8:15, ] 

#Perform the regression 
model1 <- lm(log(y) ~ log(x), data1) 
model2 <- lm(log(y) ~ log(x), data2) 
summary(model1) 
summary(model2) 

#Plot it 
with(data, plot(x, y, log="xy")) 
lines(1:7, exp(predict(model1, data.frame(x = 1:7)))) 
lines(8:15, exp(predict(model2, data.frame(x = 8:15)))) 

在一般情況下,數據分割成不同的羣體和不同的子集上運行不同的模式是不尋常的,而且很可能不好的形式。您可能需要考慮增加分組變量

data$group <- factor(rep(letters[1:2], times = 7:8)) 

,並在整個數據集運行某種模式,例如,

model_all <- lm(log(y) ~ log(x) * group, data) 
summary(model_all)