선형 회귀 분석 및 R 단위로 그룹화
다음을 사용하여 R에서 선형 회귀 분석을 수행합니다.lm()
기능.제 데이터는 연간 시계열로 한 분야(22년)와 다른 분야(50개 주)가 있습니다.각 상태에 대해 회귀 분석을 적합시켜 마지막에 lm 반응 벡터를 갖게 하려고 합니다.저는 각 상태에 대해 루프를 수행한 다음 루프 내부에서 회귀를 수행하고 각 회귀의 결과를 벡터에 추가하는 것을 상상할 수 있습니다.하지만 그것은 매우 R처럼 보이지 않습니다.SAS에서는 'by' 문을 수행하고 SQL에서는 'group by'를 수행합니다.이것을 하는 R 방법은 무엇입니까?
2009년부터.dplyr
SAS와 매우 유사한 그룹화 방법을 제공하는 릴리스가 출시되었습니다.
library(dplyr)
d <- data.frame(state=rep(c('NY', 'CA'), c(10, 10)),
year=rep(1:10, 2),
response=c(rnorm(10), rnorm(10)))
fitted_models = d %>% group_by(state) %>% do(model = lm(response ~ year, data = .))
# Source: local data frame [2 x 2]
# Groups: <by row>
#
# state model
# (fctr) (chr)
# 1 CA <S3:lm>
# 2 NY <S3:lm>
fitted_models$model
# [[1]]
#
# Call:
# lm(formula = response ~ year, data = .)
#
# Coefficients:
# (Intercept) year
# -0.06354 0.02677
#
#
# [[2]]
#
# Call:
# lm(formula = response ~ year, data = .)
#
# Coefficients:
# (Intercept) year
# -0.35136 0.09385
계수 및 R 제곱/p. 값을 검색하려면 다음을 사용할 수 있습니다.broom
꾸러미이 패키지는 다음을 제공합니다.
세 가지 S3 일반론: 회귀 계수와 같은 모델의 통계적 소견을 요약하는 정리, 예측, 잔차 및 클러스터 할당과 같은 원래 데이터에 열을 추가하는 확대, 모델 수준 통계의 한 행 요약을 제공하는 글레어.
library(broom)
fitted_models %>% tidy(model)
# Source: local data frame [4 x 6]
# Groups: state [2]
#
# state term estimate std.error statistic p.value
# (fctr) (chr) (dbl) (dbl) (dbl) (dbl)
# 1 CA (Intercept) -0.06354035 0.83863054 -0.0757668 0.9414651
# 2 CA year 0.02677048 0.13515755 0.1980687 0.8479318
# 3 NY (Intercept) -0.35135766 0.60100314 -0.5846187 0.5749166
# 4 NY year 0.09385309 0.09686043 0.9689519 0.3609470
fitted_models %>% glance(model)
# Source: local data frame [2 x 12]
# Groups: state [2]
#
# state r.squared adj.r.squared sigma statistic p.value df
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (int)
# 1 CA 0.004879969 -0.119510035 1.2276294 0.0392312 0.8479318 2
# 2 NY 0.105032068 -0.006838924 0.8797785 0.9388678 0.3609470 2
# Variables not shown: logLik (dbl), AIC (dbl), BIC (dbl), deviance (dbl),
# df.residual (int)
fitted_models %>% augment(model)
# Source: local data frame [20 x 10]
# Groups: state [2]
#
# state response year .fitted .se.fit .resid .hat
# (fctr) (dbl) (int) (dbl) (dbl) (dbl) (dbl)
# 1 CA 0.4547765 1 -0.036769875 0.7215439 0.4915464 0.3454545
# 2 CA 0.1217003 2 -0.009999399 0.6119518 0.1316997 0.2484848
# 3 CA -0.6153836 3 0.016771076 0.5146646 -0.6321546 0.1757576
# 4 CA -0.9978060 4 0.043541551 0.4379605 -1.0413476 0.1272727
# 5 CA 2.1385614 5 0.070312027 0.3940486 2.0682494 0.1030303
# 6 CA -0.3924598 6 0.097082502 0.3940486 -0.4895423 0.1030303
# 7 CA -0.5918738 7 0.123852977 0.4379605 -0.7157268 0.1272727
# 8 CA 0.4671346 8 0.150623453 0.5146646 0.3165112 0.1757576
# 9 CA -1.4958726 9 0.177393928 0.6119518 -1.6732666 0.2484848
# 10 CA 1.7481956 10 0.204164404 0.7215439 1.5440312 0.3454545
# 11 NY -0.6285230 1 -0.257504572 0.5170932 -0.3710185 0.3454545
# 12 NY 1.0566099 2 -0.163651479 0.4385542 1.2202614 0.2484848
# 13 NY -0.5274693 3 -0.069798386 0.3688335 -0.4576709 0.1757576
# 14 NY 0.6097983 4 0.024054706 0.3138637 0.5857436 0.1272727
# 15 NY -1.5511940 5 0.117907799 0.2823942 -1.6691018 0.1030303
# 16 NY 0.7440243 6 0.211760892 0.2823942 0.5322634 0.1030303
# 17 NY 0.1054719 7 0.305613984 0.3138637 -0.2001421 0.1272727
# 18 NY 0.7513057 8 0.399467077 0.3688335 0.3518387 0.1757576
# 19 NY -0.1271655 9 0.493320170 0.4385542 -0.6204857 0.2484848
# 20 NY 1.2154852 10 0.587173262 0.5170932 0.6283119 0.3454545
# Variables not shown: .sigma (dbl), .cooksd (dbl), .std.resid (dbl)
다음은 플라이어 패키지를 사용하는 방법입니다.
d <- data.frame(
state = rep(c('NY', 'CA'), 10),
year = rep(1:10, 2),
response= rnorm(20)
)
library(plyr)
# Break up d by state, then fit the specified model to each piece and
# return a list
models <- dlply(d, "state", function(df)
lm(response ~ year, data = df))
# Apply coef to each model and return a data frame
ldply(models, coef)
# Print the summary of each model
l_ply(models, summary, .print = TRUE)
다음을 사용하는 한 가지 방법이 있습니다.lme4
꾸러미
library(lme4)
d <- data.frame(state=rep(c('NY', 'CA'), c(10, 10)),
year=rep(1:10, 2),
response=c(rnorm(10), rnorm(10)))
xyplot(response ~ year, groups=state, data=d, type='l')
fits <- lmList(response ~ year | state, data=d)
fits
#------------
Call: lmList(formula = response ~ year | state, data = d)
Coefficients:
(Intercept) year
CA -1.34420990 0.17139963
NY 0.00196176 -0.01852429
Degrees of freedom: 20 total; 16 residual
Residual standard error: 0.8201316
제 생각에는 이런 종류의 데이터에 대한 더 나은 접근 방식이 혼합 선형 모델입니다.아래 코드는 전체 추세를 고정 효과로 제공합니다.랜덤 효과는 각 개별 상태의 추세가 글로벌 추세와 어떻게 다른지 나타냅니다.상관 구조는 시간적 자기 상관을 고려합니다.Pinheiro & Bates(S 및 S-Plus의 혼합 효과 모델)를 살펴보십시오.
library(nlme)
lme(response ~ year, random = ~year|state, correlation = corAR1(~year))
다음을 사용하는 좋은 솔루션data.table
@Zach가 여기 크로스 밸리데이션에 게시했습니다.회귀 계수 r^2를 반복적으로 구하는 것도 가능하다는 것을 덧붙이고 싶습니다.
## make fake data
library(data.table)
set.seed(1)
dat <- data.table(x=runif(100), y=runif(100), grp=rep(1:2,50))
##calculate the regression coefficient r^2
dat[,summary(lm(y~x))$r.squared,by=grp]
grp V1
1: 1 0.01465726
2: 2 0.02256595
다른 모든 출력뿐만 아니라summary(lm)
:
dat[,list(r2=summary(lm(y~x))$r.squared , f=summary(lm(y~x))$fstatistic[1] ),by=grp]
grp r2 f
1: 1 0.01465726 0.714014
2: 2 0.02256595 1.108173
추가할 가치가 있다고 생각합니다.purrr::map
이 문제에 대한 접근법
library(tidyverse)
d <- data.frame(state=rep(c('NY', 'CA'), c(10, 10)),
year=rep(1:10, 2),
response=c(rnorm(10), rnorm(10)))
d %>%
group_by(state) %>%
nest() %>%
mutate(model = map(data, ~lm(response ~ year, data = .)))
사용에 대한 자세한 내용은 @Paul Hiemstra의 답변을 참조하십시오.broom
이러한 결과가 포함된 패키지.
지금은 답변이 조금 늦었지만 비슷한 기능을 찾고 있었습니다.R의 내장 함수 'by'도 그룹화를 쉽게 수행할 수 있는 것 같습니다.
?by에는 그룹당 적합하고 sapply로 계수를 추출하는 다음 예제가 포함되어 있습니다.
require(stats)
## now suppose we want to extract the coefficients by group
tmp <- with(warpbreaks,
by(warpbreaks, tension,
function(x) lm(breaks ~ wool, data = x)))
sapply(tmp, coef)
## make fake data
ngroups <- 2
group <- 1:ngroups
nobs <- 100
dta <- data.frame(group=rep(group,each=nobs),y=rnorm(nobs*ngroups),x=runif(nobs*ngroups))
head(dta)
#--------------------
group y x
1 1 0.6482007 0.5429575
2 1 -0.4637118 0.7052843
3 1 -0.5129840 0.7312955
4 1 -0.6612649 0.9028034
5 1 -0.5197448 0.1661308
6 1 0.4240346 0.8944253
#------------
## function to extract the results of one model
foo <- function(z) {
## coef and se in a data frame
mr <- data.frame(coef(summary(lm(y~x,data=z))))
## put row names (predictors/indep variables)
mr$predictor <- rownames(mr)
mr
}
## see that it works
foo(subset(dta,group==1))
#=========
Estimate Std..Error t.value Pr...t.. predictor
(Intercept) 0.2176477 0.1919140 1.134090 0.2595235 (Intercept)
x -0.3669890 0.3321875 -1.104765 0.2719666 x
#----------
## one option: use command by
res <- by(dta,dta$group,foo)
res
#=========
dta$group: 1
Estimate Std..Error t.value Pr...t.. predictor
(Intercept) 0.2176477 0.1919140 1.134090 0.2595235 (Intercept)
x -0.3669890 0.3321875 -1.104765 0.2719666 x
------------------------------------------------------------
dta$group: 2
Estimate Std..Error t.value Pr...t.. predictor
(Intercept) -0.04039422 0.1682335 -0.2401081 0.8107480 (Intercept)
x 0.06286456 0.3020321 0.2081387 0.8355526 x
## using package plyr is better
library(plyr)
res <- ddply(dta,"group",foo)
res
#----------
group Estimate Std..Error t.value Pr...t.. predictor
1 1 0.21764767 0.1919140 1.1340897 0.2595235 (Intercept)
2 1 -0.36698898 0.3321875 -1.1047647 0.2719666 x
3 2 -0.04039422 0.1682335 -0.2401081 0.8107480 (Intercept)
4 2 0.06286456 0.3020321 0.2081387 0.8355526 x
그lm()
위의 함수는 간단한 예입니다.참고로 데이터베이스에 다음과 같은 열이 있을 것으로 생각됩니다.
연도 상태 var1 var2 y...
다음 코드를 사용할 수 있습니다.
require(base)
library(base)
attach(data) # data = your data base
#state is your label for the states column
modell<-by(data, data$state, function(data) lm(y~I(1/var1)+I(1/var2)))
summary(modell)
문제는 루프 내에서 수정된 공식으로 회귀 함수를 호출하는 방법에 관한 것으로 보입니다.
(다이아몬드 데이터 세트 사용)에서 수행할 수 있는 방법은 다음과 같습니다.
attach(ggplot2::diamonds)
strCols = names(ggplot2::diamonds)
formula <- list(); model <- list()
for (i in 1:1) {
formula[[i]] = paste0(strCols[7], " ~ ", strCols[7+i])
model[[i]] = glm(formula[[i]])
#then you can plot the results or anything else ...
png(filename = sprintf("diamonds_price=glm(%s).png", strCols[7+i]))
par(mfrow = c(2, 2))
plot(model[[i]])
dev.off()
}
언급URL : https://stackoverflow.com/questions/1169539/linear-regression-and-group-by-in-r
'code' 카테고리의 다른 글
C의 2D 배열 포인터 (0) | 2023.06.12 |
---|---|
C 스타일 언어에서 익명 {}개 블록의 목적은 무엇입니까? (0) | 2023.06.12 |
가상 환경 복제 방법 (0) | 2023.06.12 |
attr_accessor와 attr_accessible의 차이 (0) | 2023.06.12 |
메타클래스의 (구체적인) 사용 사례는 무엇입니까? (0) | 2023.06.12 |