Изучая data.table
, я обнаружил ситуацию, которую не могу элегантно обойти.
Напротив: абсурд формулы lm
очевиден, я пытаюсь определить, можно ли легко обойти этот нюанс с помощью ключевого слова или специального оператора в экосистеме data.table
.
library(data.table)
mt <- as.data.table(mtcars)
mt[, list(model = list(lm(mpg ~ disp))), by = "cyl"]
# cyl model
# 1: 6 <lm>
# 2: 4 <lm>
# 3: 8 <lm>
mt[, list(model = list(lm(mpg ~ disp + cyl))), by = "cyl"]
# Error in model.frame.default(formula = mpg ~ disp + cyl, drop.unused.levels = TRUE) :
# variable lengths differ (found for 'cyl')
Это потому, что внутри блока cyl
является вектором длины 1, а не столбцом, как остальные значения:
mt[, list(model = { browser(); list(lm(mpg ~ cyl+disp)); }), by = "cyl"]
# Called from: '[.data.table'(mt, , list(model = {
# browser()
# list(lm(mpg ~ cyl + disp))
# ...
# Browse[1]>
# debug at #1: list(lm(mpg ~ cyl + disp))
# Browse[2]>
disp
# [1] 160.0 160.0 258.0 225.0 167.6 167.6 145.0
# Browse[2]>
cyl
# [1] 6
Наиболее простым представляется, как представляется, вручную удлинить его внутренне как временную переменную или буквально при необходимости:
mt[, list(model = { cyl2 <- rep(cyl, nrow(.SD)); list(lm(mpg ~ cyl2+disp)); }), by = "cyl"]
mt[, list(model = list(lm(mpg ~ rep(cyl, nrow(.SD))+disp))), by = "cyl"]
В: Есть ли более элегантный способ справиться с этим?
Различные слабо связанные вопросы, которые вызывают у меня любопытство (к внедрению "вещей" в объекты DT):
- Задание имени столбца в операции "group by" с data.table
- Запустите функцию внутри data.table в R
- Использование data.table для создания столбца коэффициентов регрессии
Кандидатов пока много, хороших
mt[, .(model = .(lm(mpg ~ cyl + disp, data = mt[.I]))), by = .(cyl)]
mt[, .(model = .(lm(mpg ~ cyl + disp))), by =.(cylgroup=cyl)]
mt[, .(model = .(lm(mpg ~ cyl + disp, .SD))), by=cyl, .SDcols=names(mt)]
mt[, .(model = .(lm(mpg ~ cyl + disp, .SD))), by=cyl, .SDcols=TRUE]
mt[, .(model = .(lm(mpg ~ cyl + disp, data = cbind(.SD, as.data.table(.BY))))), by = "cyl"]