লিনিয়ার রিগ্রেশন এবং গ্রুপ দ্বারা আর


97

আমি lm()ফাংশনটি ব্যবহার করে আর-তে একটি লিনিয়ার রিগ্রেশন করতে চাই । আমার ডেটা হ'ল একটি বার্ষিক সময় সিরিজ যা একটি ক্ষেত্র বছরের জন্য (22 বছর) এবং অন্যটি রাজ্যের (50 টি রাজ্যের) জন্য। আমি প্রতিটি রাজ্যের জন্য একটি রিগ্রেশন ফিট করতে চাই যাতে শেষে আমার কাছে এলএম প্রতিক্রিয়াগুলির একটি ভেক্টর থাকে। আমি প্রতিটি রাষ্ট্রের জন্য লুপের জন্য করার পরে লুপের অভ্যন্তরে রিগ্রেশন করে এবং প্রতিটি প্রতিরোধের ফলাফলগুলি একটি ভেক্টরে যুক্ত করার কল্পনা করতে পারি। তবে এটি আর-এর মতো মনে হয় না। এসএএস-তে আমি একটি 'বাই' স্টেটমেন্ট করব এবং এসকিউএল-তে আমি একটি 'গ্রুপ বাই' করব। এটি করার আর কি উপায়?


4
কেবলমাত্র লোকদেরই বলতে চাই যে যদিও আর-তে প্রচুর গ্রুপ-বাই ফাংশন রয়েছে তবে তাদের সমস্তই গ্রুপ-বাই রিগ্রেশনের জন্য সঠিক নয়। উদাহরণস্বরূপ, aggregateএকটি সঠিক এক নয় ; না হয়tapply
21

উত্তর:


51

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

4
এই দুটি মডেলের উভয়ের জন্যই কি আর 2 তালিকাভুক্ত করার কোনও উপায় আছে? যেমন বছরের পর বছর একটি আর 2 কলাম যুক্ত করুন। এছাড়াও প্রতিটি কোফের জন্য পি-মান যুক্ত করবেন?
টুরোরো

4
@ টোটোআরো এখানে আপনি একটি সম্ভাব্য সমাধান খুঁজে পেতে পারেন (আগের তুলনায় আরও দেরি): আপনার ডিডিএফ [, সারাংশ (এলএম (ওয়াই-এক্স)) $ r.squared, দ্বারা = আপনার.ফ্যাক্টর] যেখানে: ওয়াই, এক্স এবং আপনার.ফ্যাক্টর আপনার পরিবর্তনশীল। দয়া করে মনে রাখবেন যে আপনার.ডিএফ অবশ্যই একটি ডেটা টেবিল ক্লাস হতে হবে
ফ্রেটনেট

60

প্লাইর প্যাকেজটি ব্যবহার করে এখানে একটি পদ্ধতির কথা :

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)

বলুন আপনি একটি অতিরিক্ত স্বতন্ত্র ভেরিয়েবল যুক্ত করেছেন যা সমস্ত রাজ্যে (যেমন মাইল.ওফ.সোশন.শোরলাইন) উপলভ্য ছিল না যা আপনার ডেটাতে এনএ দ্বারা প্রতিনিধিত্ব করা হয়েছিল। এলএম কল ব্যর্থ হবে না? কীভাবে এটি মোকাবেলা করা যেতে পারে?
মাইকটিপি

ফাংশনের অভ্যন্তরে আপনাকে সেই ক্ষেত্রে পরীক্ষা করতে হবে এবং একটি আলাদা সূত্র ব্যবহার করতে হবে
হ্যাডলি

সারাংশের (শেষ পদক্ষেপ) প্রতিটি কলটিতে উপগোষ্ঠীর নাম যুক্ত করা কি সম্ভব?
এর্ক

আপনি যদি চালনা করেন layout(matrix(c(1,2,3,4),2,2)) # optional 4 graphs/page এবং তারপরে l_ply(models, plot)আপনি প্রতিটি অবশিষ্ট প্লটও পেয়ে থাকেন। গ্রুপের সাথে প্রতিটি প্লটকে লেবেল করা সম্ভব (উদাহরণস্বরূপ, এই ক্ষেত্রে "রাজ্য")?
ব্রায়ান ডি

51

২০০৯ সাল dplyrথেকে মুক্তি পেয়েছে যা এসএএস কী করে তা ঘনিষ্ঠভাবে সাদৃশ্যযুক্ত এই ধরণের গ্রুপিং করার জন্য খুব সুন্দর উপায় সরবরাহ করে।

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  

সহগ এবং রিকোয়ার্ড / পি। মূল্য পুনরুদ্ধার করতে, broomপ্যাকেজটি ব্যবহার করতে পারেন । এই প্যাকেজটি সরবরাহ করে:

তিনটি এস 3 জেনেরিক্স: পরিপাটি, যা কোনও মডেলের পরিসংখ্যানগত ফলাফলগুলি সংক্ষেপণের সহগ হিসাবে যেমন সংক্ষিপ্তসার করে; বর্ধন, যা পূর্বাভাস, অবশিষ্টাংশ এবং ক্লাস্টার অ্যাসাইনমেন্টের মতো মূল ডেটাতে কলাম যুক্ত করে; এবং এক নজরে, যা মডেল-স্তরের পরিসংখ্যানগুলির এক-সারির সারসংক্ষেপ সরবরাহ করে।

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)

4
rowwise(fitted_models) %>% tidy(model)কাজ করার জন্য ঝাড়ু প্যাকেজটি পেতে আমাকে করতে হয়েছিল তবে অন্যথায় দুর্দান্ত উত্তর।
পেড্রাম

4
দুর্দান্ত কাজ করে ... পাইপটি ছাড়াই d %>% group_by(state) %>% do(model = lm(response ~ year, data = .)) %>% rowwise() %>% tidy(model)
এগুলি

4
@ পেড্রাম এবং @ হোলাস্টেলো, এটি আর আর কাজ করে না, কমপক্ষে আর 6.6.১, ব্রুম .7..7.০, ডিপিপ্লায়ার ৮.০.৩ নিয়ে। d %>% group_by(state) %>% do(model=lm(response ~year, data = .)) %>% rowwise() %>% tidy(model) Error in var(if (is.vector(x) || is.factor(x)) x else as.double(x), na.rm = na.rm) : Calling var(x) on a factor x is defunct. Use something like 'all(duplicated(x)[-1L])' to test for a constant vector. In addition: Warning messages: 1: Data frame tidiers are deprecated and will be removed in an upcoming release of broom. ...
ক্রিস নোল্টে

24

আমার মতে একটি মিশ্র লিনিয়ার মডেল এই ধরণের ডেটার জন্য আরও ভাল পদ্ধতির। নীচের কোডটি নির্দিষ্ট প্রভাবটিতে দেওয়া হয়েছে সামগ্রিক প্রবণতা। এলোমেলো প্রভাবগুলি নির্দেশ করে যে কীভাবে প্রতিটি পৃথক রাষ্ট্রের প্রবণতা বৈশ্বিক প্রবণতা থেকে আলাদা। পারস্পরিক সম্পর্ক কাঠামোগত স্বতঃসংশোধনকে অ্যাকাউন্টে নেয় into পিনহেরো অ্যান্ড বেটস (এস এবং এস-প্লাসের মিশ্র প্রভাবসমূহ) দেখুন।

library(nlme)
lme(response ~ year, random = ~year|state, correlation = corAR1(~year))

4
এটি সত্যিই একটি ভাল সাধারণ পরিসংখ্যান তত্ত্বের উত্তর যা আমাকে কিছু জিনিস বিবেচনা না করার বিষয়ে চিন্তা করতে বাধ্য করে। যে অ্যাপ্লিকেশনটি আমাকে প্রশ্ন জিজ্ঞাসা করেছিল তা এই সমাধানের জন্য প্রযোজ্য হবে না তবে আপনি খুশি হয়ে আপনি এটি উত্থাপন করেছেন। ধন্যবাদ.
জেডি লং

4
একটি মিশ্র মডেল দিয়ে শুরু করা ভাল ধারণা নয় - আপনি কীভাবে জানবেন যে অনুমানগুলির কোনওটি নিশ্চিত?
হ্যাডলি

8
মডেল বৈধতা (এবং ডেটা জ্ঞান) দ্বারা ধারণা অনুধাবন করা উচিত। বিটিডাব্লু আপনি স্বতন্ত্র এলএম এর অনুমানের ওয়্যারেন্ট করতে পারবেন না। আপনাকে সমস্ত মডেলকে আলাদাভাবে বৈধতা দিতে হবে।
থিয়েরি

17

ব্যবহার করে একটি দুর্দান্ত সমাধান এখানেdata.table পোস্ট করা হয়েছে @ জাচ দ্বারা ক্রসভিলেটেডে। আমি কেবল যুক্ত করব যে পুনরাবৃত্তির গুণাগুণগুলিও পুনরাবৃত্তভাবে প্রাপ্ত করা সম্ভব 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

8

আমি মনে করি 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 = .)))

broomএই ফলাফলগুলি সহ প্যাকেজটি ব্যবহার করার বিষয়ে আরও ধারণার জন্য @ পল হিমস্ট্রার উত্তর দেখুন ।


আপনি লাগানো মান বা অবশিষ্টাংশগুলির একটি কলাম চাইলে কিছুটা প্রসারিত করুন: একটি রেসিড () কলটিতে lm () কলটি মোড়ানো এবং তারপরে সর্বশেষ লাইনের সমস্ত কিছুকে একটি অযৌক্তিক () কলটিতে পাইপ করুন। অবশ্যই, আপনি পরিবর্তনশীল নামটি "মডেল" থেকে আরও প্রাসঙ্গিক কিছুতে পরিবর্তন করতে চান।
এলোমেলো

8
## 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

7

আমি এখন আমার উত্তরটি কিছুটা দেরিতে এসেছি, তবে আমি অনুরূপ কার্যকারিতাটি খুঁজছিলাম। এটি आर-এর অন্তর্নির্মিত ফাংশনটি সহজেই গ্রুপিং করতে পারে:

? দ্বারা নিম্নলিখিত উদাহরণ রয়েছে, যা প্রতি গ্রুপে ফিট করে এবং গুণের সাথে সহগগুলি বের করে:

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)

4

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)

0

প্রশ্নটি লুপের অভ্যন্তরে পরিবর্তিত সূত্রগুলি সহ রিগ্রেশন ফাংশনগুলিকে কীভাবে কল করবেন সে সম্পর্কে মনে হচ্ছে।

আপনি এখানে এটি কীভাবে করতে পারেন তা এখানে (হীরার ডেটাসেট ব্যবহার করে):

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()
  }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.