r - 按组快速线性回归

标签 r dplyr lm

我有50万个用户,我需要为每个用户计算线性回归(带截距)。

每个用户大约有30条记录。

我尝试使用dplyrlm,这太慢了。
用户大约2秒。

  df%>%                       
      group_by(user_id, add =  FALSE) %>%
      do(lm = lm(Y ~ x, data = .)) %>%
      mutate(lm_b0 = summary(lm)$coeff[1],
             lm_b1 = summary(lm)$coeff[2]) %>%
      select(user_id, lm_b0, lm_b1) %>%
      ungroup()
    )


我尝试使用已知更快的lm.fit,但它似乎与dplyr不兼容。

是否有按组进行线性回归的快速方法?

最佳答案

您可以使用基本公式来计算斜率和回归。如果您只关心这两个数字,lm会做很多不必要的事情。在这里,我使用data.table进行聚合,但是您也可以在base R(或dplyr)中进行此操作:

system.time(
  res <- DT[, 
    {
      ux <- mean(x)
      uy <- mean(y)
      slope <- sum((x - ux) * (y - uy)) / sum((x - ux) ^ 2)
      list(slope=slope, intercept=uy - slope * ux)
    }, by=user.id
  ]
)


为500K用户产生约30磅(以秒为单位)的内容:

 user  system elapsed 
 7.35    0.00    7.36 


或每个用户约15微秒。

更新:我最后写了一堆与此相关的blog posts

并确认这按预期工作:

> summary(DT[user.id==89663, lm(y ~ x)])$coefficients
             Estimate Std. Error   t value  Pr(>|t|)
(Intercept) 0.1965844  0.2927617 0.6714826 0.5065868
x           0.2021210  0.5429594 0.3722580 0.7120808
> res[user.id == 89663]
   user.id    slope intercept
1:   89663 0.202121 0.1965844


数据:

set.seed(1)
users <- 5e5
records <- 30
x <- runif(users * records)
DT <- data.table(
  x=x, y=x + runif(users * records) * 4 - 2, 
  user.id=sample(users, users * records, replace=T)
)

关于r - 按组快速线性回归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29803993/

相关文章:

r - 如何将 R 中存储为字符的指数转换为数值?

regex - 点元字符如何匹配换行符?

r - 将向量解包到列表中,向量的每个元素作为列表中的单独元素

regex - 如何从包含特定文本的数据框列中提取数据

根据 R 中特定列中的值替换所有行值

r - 总结中的 p 值与 R lm() 中的方差分析之间的差异

结果集错误 : Issue knitting RMarkdown with SQL connection

r - 通过与列表变量值匹配来改变列

删除残差图中的 xlab(fit,which = 1)

r - 如何简洁地编写包含数据框中许多变量的公式?