【问题标题】:Run a function inside data.table in R在 R 中的 data.table 中运行一个函数
【发布时间】:2018-10-31 16:46:14
【问题描述】:

您好,我在 R 中有一些 data.table 格式的数据,我需要运行一些函数。

假设我有一个名为 A 的 data.table,其中包含“名称”、“高度”、“重量”等列。

我想运行一些函数,即 data.table 中的线性回归并将系数 RMSE 存储到表结果中。

A[, .(beta = lm(height ~ weight)$coefficients[2], RMSE = 
     as.numeric(sqrt(crossprod(lm(height 
     ~ weight)$residuals)/(length(lm(height ~ weight)$residuals)- 
     (length(coef(lm(height ~ weight)))-1)))*100),
     by=.(name)]

我的问题:有没有办法将 lm(height ~ weight) 结果保存为一个对象,然后访问这个对象的数据,这样 data.table 就不需要在这里运行 lm 函数 4 次?

这运行,但与我使用 foreach 和循环“名称”相比它有点太慢,因为我有数百万行数据。

谢谢。

【问题讨论】:

  • 这确实引出了“整洁”工作的问题(参考了大部分 tidyverse),但速度/效率与 data.table 一样。有趣的是,我会寻找一个很好的讨论/教育!
  • 目前,如果我运行 lm 函数只获取系数,则需要 2 秒。如果我需要运行 lm 函数 4 次来计算 RMSE,它需要 12 秒!我现在已经习惯了 data.table 语法,但是随着 tidyverse 的规模越来越大,我可能需要同时学习这两种语法!
  • 相关:data.table: anonymous function in j。使用{ }j 中的匿名机构。用你想要的任何功能填充它(例如lm!)。最后,将所需的返回变量包装在list( )(或点别名.( ))中。
  • 在此处查看答案中的示例:Using data.table to create a column of regression coefficients,例如第二个使用{ } 并首先创建“辅助”对象,然后在list(...) 中返回列。
  • 另外,lm() 也很慢,因为它做的太多了——lm.fit() 是一个更简单的选择,但你可能必须计算自己的残差。而且您可能不想为了方便而多次运行lm()

标签: r data.table


【解决方案1】:

通过使用 Henrik 建议的匿名正文,我可以加快进程!

A[, {model <- lm(height ~ weight)
       BETA <- model$coefficient[2]
       RMSE <- as.numeric(sqrt(crossprod(model$residuals)/(length(model$residuals)- 
               (length(coef(model))-1)))*100)

       list(BETA = BETA, RMSE = RMSE)
       },
 by = .(name)]

显然,匿名主体 (lambda) 不需要名称,它就像“运行一次就忘记”。在这个 lambda 中,lm() 函数运行一次(每组),结果存储在一个对象中。

然后我们可以从模型对象中提取所需的数据,最后提供list()j将提取的​​数据转换成列。

非常感谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2014-06-08
    相关资源
    最近更新 更多