#r #data.table #rcpparmadillo
#r #данные.таблица #rcpparmadillo
Вопрос:
Я пытаюсь использовать функцию RcppArmadillo::fastLM
вместо из lm
соображений производительности. Вот мой вызов функции для lm
test_dt = structure(list(A= c(168.08, 166.65, 167.52, 167.16, 165.77, 167.65, 169.84, 170.45, 171.29, 173.15, 174.12, 174.45, 174.18, 172.92, 174.5, 173.94, 172.61, 168.74, 167.28, 167.12), `B` = c(1801.599976, 1783, 1795.099976, 1788.699951, 1763.599976, 1793, 1816.400024, 1827.400024, 1830.199951, 1847.599976, 1863.199951, 1867.900024, 1866.099976, 1853.599976, 1869.699951, 1861, 1851.199951, 1806, 1783.5, 1784.099976)), row.names = c(NA, -20L), class = c("data.table", "data.frame")) coef(lm(A ~ B 0,data = test_dt))[1] gt; 0.0934728
поскольку большая часть времени используется lm при интерпретации формулы, я не хочу использовать формулу. Вместо этого я хочу превратить это во что-то —
RcppArmadillo::fastLM(X = test_dt$B 0, y = test_dt$A)
но я не уверен, как добавить 0
, как показано в формуле.
Я попробовал следующее
library(data.table) dt = copy(test_dt) dt[, C := 0] coef(RcppArmadillo::fastLm(X = dt[,2:3], y = dt[,1]))[[1]]
Но это дает ошибку.
Error in fastLm.default(X = dt[, 2:3], y = dt[, 1]) : (list) object cannot be coerced to type 'double'
Может ли кто-нибудь показать мне правильный способ превращения формулы A ~ B 0
в переменные X
и y
для использования в функции fastLm?
Вот результаты работы.
microbenchmark::microbenchmark( formula = coef(lm(A ~ B 0, dt))[1], fastLm = with(dt, coef(RcppArmadillo::fastLm(B, A)))[1], flm = with(dt, collapse::flm(A, cbind(B)))[1], times = 100)
Unit: microseconds expr min lq mean median uq max neval cld formula 1157.822 1173.249 1191.57071 1183.0080 1197.5560 1714.430 100 c fastLm 219.785 228.086 240.30415 235.2545 244.7465 405.353 100 b flm 67.595 71.902 76.91765 74.7790 77.2050 228.320 100 a
Комментарии:
1. Можете ли вы попробовать метод формулы, т. е.
fastLm(A ~ B 0, data = dt)
2. Метод формулы работает нормально. Единственная проблема заключается в том, что использование формулы в 3 раза медленнее.
3. В первой формуле , которую вы использовали
A ~ B 0
, но во второй вы используетеy
какB
, это опечатка4. Да, это была опечатка, я ее исправил. Спасибо.
5. Вам нужно
fastLm(X = dt[, 2:3], y = dt[[1]])
Ответ №1:
Первым аргументом метода fastLm по умолчанию является матрица модели. Он должен иметь столбец 1 для представления перехвата, а если это не так, то перехвата нет.
Они дают один и тот же ответ, не используя перехват:
coef(lm(A ~ B 0, test_dt))[1] with(test_dt, coef(fastLm(B, A)))
и они дают один и тот же ответ, используя перехват:
coef(lm(A ~ B, test_dt)) with(test_dt, coef(fastLm(cbind(1, B), A)))
Комментарии:
1. Спасибо, @Grothendieck, это сработало идеально. Я поделился результатами работы выше.
2. Вы также можете попробовать flm в пакете свернуть. Он использует те же аргументы, что и fastLm, но в обратном порядке, и возвращает только коэффициенты, поэтому с ним не используется coef.
3. Спасибо за указатель. Я пытался
library(collapse) with(dt, collapse::flm(X = B, y = A, method = "lm"))
, но это ошибкаif (n != NROW(y)) stop("NROW(y) must match nrow(X)")
. Похоже, что внутриflm
функционируют обаdim(dt$A)
иnrow(dt$B)
терпят неудачу.4. Используя test_dt из вопроса, они оба работают для меня:
library(collapse); with(test_dt, flm(A, cbind(B)))
- кажется, что B не может быть вектором, но должен быть матрицей, и используя ту же инструкцию библиотеки:with(test_dt, flm(A, cbind(1, B)))
5. Вау,
flm
это еще быстрее. Я обновил результаты работы. Большое вам спасибо!
Ответ №2:
Это y
должен быть вектор. Согласно с ?fastLm
y - вектор, содержащий объясняемую переменную.
С помощью dt[,1]
, drop = FALSE
в data.table
котором возвращает таблицу data.table с одним столбцом. Вместо этого, если нам нужен вектор, используйте [[
для извлечения столбца
fastLm(X = dt[, 2:3], y = dt[[1]])
Комментарии:
1. Есть ли способ удалить предупреждение?
solve(): system is singular; attempting approx solution
2. @Saurabh когда вы говорите удалить предупреждение, вы хотите
suppressWarnings
3. Нет :), я имел в виду, есть ли что-то еще, что я делаю неправильно во время звонка
fastLm
. Я попытался превратить X в матрицу, но ошибка все равно есть.