簡體   English   中英

在R中,創建模型時,是否與SAS中的by語句等效?

[英]In R, when creating a model, is there an equivalent to the by statement in SAS?

假設我有一個數據集,我想為變量A和B的每種組合創建一個lm。其中A具有兩個值:'a'和'b',而B具有三個值:1,2,3 。 這給了我變量A和B的六個可能組合。

也就是說,我想創建六(6)個模型。 在示例中,第一個模型將具有數據子集,其中A = a和B = 1。

例如,在SAS中,代碼如下(請注意by語句):

proc glm data = mydate;
by A B;
class Cat1 Cat2;
model Y = X + Cat1 + Cat2;
run;

by語句將為A和B的組合生成一個模型。

這實際上只是一個拆分步驟:

  1. 將數據分成大塊

     smydate <- split(mydate, list(A = A, B = B)) 

    smydate每個成分代表AB特定組合的數據。 如果您的數據未包含AB級別的所有組合,則可能需要在split調用中添加drop = TRUE

  2. 在列表smydate的組件上應用lm()函數

     lmFun <- function(dat) { lm(y ~ x + cat1 + cat2, data = dat) } models <- lapply(smydate, lmFun) 

現在您有了一個models列表,其中每個組件都包含一個針對AB特定組合的lm對象。

一個示例(基於rawr在注釋中顯示的示例是:

models <- lapply(split(mtcars, list(mtcars$am, mtcars$gear), drop = TRUE),
                 function(x) {lm(mpg ~ wt + disp, data = x)})
str(models)
models

這使:

> str(models, max = 1)
List of 4
 $ 0.3:List of 12
  ..- attr(*, "class")= chr "lm"
 $ 0.4:List of 12
  ..- attr(*, "class")= chr "lm"
 $ 1.4:List of 12
  ..- attr(*, "class")= chr "lm"
 $ 1.5:List of 12
  ..- attr(*, "class")= chr "lm"
> models
$`0.3`

Call:
lm(formula = mpg ~ wt + disp, data = x)

Coefficients:
(Intercept)           wt         disp  
  27.994610    -2.384834    -0.007983  


$`0.4`

Call:
lm(formula = mpg ~ wt + disp, data = x)

Coefficients:
(Intercept)           wt         disp  
   219.1047    -106.8075       0.9953  


$`1.4`

Call:
lm(formula = mpg ~ wt + disp, data = x)

Coefficients:
(Intercept)           wt         disp  
   43.27860     -3.03114     -0.09481  


$`1.5`

Call:
lm(formula = mpg ~ wt + disp, data = x)

Coefficients:
(Intercept)           wt         disp  
  41.779042    -7.230952    -0.006731  

如注釋中的rawr注釋所示,您可以使用by()或使用plyr包中的許多其他更高級別的函數中的任何一個,以較少的步驟完成此操作,但是手工操作至少說明了該方法的普遍性。方法 熟悉總體思路后,您始終可以使用快捷方式。

更具體地說,在使用@bjoseph的生成交互變量的策略之后,可以使用lmList將線性模型擬合到類別:

mydate <- transform(mydate, ABcat=interaction(A,B,drop=TRUE))
library("lme4")  ## or library("nlme")
lmList(Y~X+Cat1+Cat2|ABcat,mydate)

dplyr包中使用group_by將對每個子組組合運行分析。 使用mtcars數據集:

library(dplyr)
res <- mtcars %>%
  group_by(am, gear) %>%
  do(mod = lm(mpg ~ wt + disp, data = .))

res$mod

將為您提供lm對象的列表。

其他包裝將使之更加優雅。 您可以使用magrittr軟件包直接進行此操作,然后直接轉到lm對象列表:

library(magrittr)
mtcars %>%
  group_by(am, gear) %>%
  do(mod = lm(mpg ~ wt + disp, data = .)) %>%
  use_series(mod)

或使用掃帚包從lm對象中提取系數值:

library(broom)
mtcars %>%
  group_by(am, gear) %>%
  do(mod = lm(mpg ~ wt + disp, data = .)) %>%
  glance(mod)

Source: local data frame [4 x 13]
Groups: am, gear

  am gear r.squared adj.r.squared     sigma statistic    p.value df     logLik      AIC      BIC  deviance df.residual
1  0    3 0.6223489     0.5594070 2.2379851  9.887679 0.00290098  3 -31.694140 71.38828 74.22048 60.102926          12
2  0    4 0.9653343     0.8960028 0.9899495 13.923469 0.18618733  3  -2.862760 13.72552 11.27070  0.980000           1
3  1    4 0.7849464     0.6989249 2.9709337  9.125006 0.02144702  3 -18.182504 44.36501 44.68277 44.132234           5
4  1    5 0.9827679     0.9655358 1.2362092 57.031169 0.01723212  3  -5.864214 19.72843 18.16618  3.056426           2

您可以嘗試幾種不同的方法。

假設我們的數據是:

structure(list(A = structure(c(1L, 1L, 2L, 2L), .Label = c("A", "B"), class = "factor"), B = structure(c(1L, 2L, 1L, 2L), .Label = c("A", "B"), class = "factor"), x = c(1, 2, 3, 4), y = c(2, 2, 2, 2)), .Names = c("A", "B", "x", "y"), row.names = c(NA, -4L), class = "data.frame")
x
#>   A B x y
   1 A A 1 2
   2 A B 2 2
   3 B A 3 2
   4 B B 4 2

通過()

這將返回一個列表類型的對象。 請注意,它不會按我們期望的順序返回結果。 它試圖在迭代時保持第二個因素盡可能穩定。 您可以使用list(x$B,x$A)

by(x[c("x","y")],list(x$A,x$B),function(x){x[1]*x[2]})
[1] 2
------------------------------------------------------------------------------------- 
[1] 6
------------------------------------------------------------------------------------- 
[1] 4
------------------------------------------------------------------------------------- 
[1] 8

expand.grid()

這是一個簡單的for循環,其中我們預先生成了感興趣的組合,在循環中將數據子集並執行了感興趣的功能。 在使用大量組合時, expand.grid()可能會變慢,並且for循環不一定很快,但是您在中間有很多控制權。

combinations = expand.grid(levels(x$A),levels(x$B))
for(i in 1:nrow(combinations)){
  d = x[x$A==combinations[i,1] & x$B==combinations[i,2],c("x","y")]
  print(d[1]*d[2])
}
#>   x
   1 2
     x
   3 6
     x
   2 4
     x
   4 8

如果您要擬合/預測而不是匯總統計(t檢驗等),則更容易擬合Y~(A:B)*(X + Cat1 + Cat2) - 1 - X - Cat1 - Cat2的交互模型; 通過減去主要影響,R將重新參數化並將所有方差置於交互作用上。 這是一個例子:

> mtcars <- within(mtcars, {cyl = as.factor(cyl); am=as.factor(am)})
> model <- lm(mpg~(cyl:am)*(hp+wt)-1-hp-wt, mtcars)
> summary(model)

Call:
lm(formula = mpg ~ (cyl:am) * (hp + wt) - 1 - hp - wt, data = mtcars)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.6685 -0.9071  0.0000  0.7705  4.1879 

Coefficients: (1 not defined because of singularities)
              Estimate Std. Error t value Pr(>|t|)    
cyl4:am0     2.165e+01  2.252e+01   0.961   0.3517    
cyl6:am0     6.340e+01  4.245e+01   1.494   0.1560    
cyl8:am0     2.746e+01  5.000e+00   5.492 6.20e-05 ***
cyl4:am1     4.725e+01  5.144e+00   9.184 1.51e-07 ***
cyl6:am1     2.320e+01  3.808e+01   0.609   0.5515    
cyl8:am1     1.877e+01  1.501e+01   1.251   0.2302    
cyl4:am0:hp -4.635e-02  1.107e-01  -0.419   0.6815    
cyl6:am0:hp  7.425e-03  1.650e-01   0.045   0.9647    
cyl8:am0:hp -2.110e-02  2.531e-02  -0.834   0.4175    
cyl4:am1:hp -7.288e-02  4.457e-02  -1.635   0.1228    
cyl6:am1:hp -2.000e-02  4.733e-02  -0.423   0.6786    
cyl8:am1:hp -1.127e-02  4.977e-02  -0.226   0.8240    
cyl4:am0:wt  1.762e+00  5.341e+00   0.330   0.7460    
cyl6:am0:wt -1.332e+01  1.303e+01  -1.022   0.3231    
cyl8:am0:wt -2.025e+00  1.099e+00  -1.843   0.0851 .  
cyl4:am1:wt -6.465e+00  2.467e+00  -2.621   0.0193 *  
cyl6:am1:wt -4.926e-15  1.386e+01   0.000   1.0000    
cyl8:am1:wt         NA         NA      NA       NA    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.499 on 15 degrees of freedom
Multiple R-squared:  0.9933,    Adjusted R-squared:  0.9858 
F-statistic: 131.4 on 17 and 15 DF,  p-value: 3.045e-13

與cyl4:am1子模型進行比較:

> summary(lm(mpg~wt+hp, mtcars, subset=cyl=='4' & am=='1'))

Call:
lm(formula = mpg ~ wt + hp, data = mtcars, subset = cyl == "4" & 
    am == "1")

Residuals:
    Datsun 710       Fiat 128    Honda Civic Toyota Corolla      Fiat X1-9  Porsche 914-2 
      -2.66851        4.18787       -2.61455        3.25523       -2.62538       -0.77799 
  Lotus Europa     Volvo 142E 
       1.17181        0.07154 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 47.24552    6.57304   7.188 0.000811 ***
wt          -6.46508    3.15205  -2.051 0.095512 .  
hp          -0.07288    0.05695  -1.280 0.256814    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.193 on 5 degrees of freedom
Multiple R-squared:  0.6378,    Adjusted R-squared:  0.493 
F-statistic: 4.403 on 2 and 5 DF,  p-value: 0.07893

系數的估計值完全相同 ,並且此處的標准誤更高/更保守,因為僅從子集中估計s ,而不是在所有模型中進行匯總。 從統計上來說,合並可能適合您的用例,也可能不適合。

獲得預測也容易得多: predict(model, X)與必須再次拆分應用合並。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM