Вычислить несколько столбцов из одной функции и добавить их в data.frame

Я хочу вернуть несколько результатов из функции в столбцах data.frame и добавить эти новые столбцы в один и тот же data.frame вместе с другими простыми вычислениями.

Для упрощенного примера, если я хочу получить как интегральное значение, так и абсолютную ошибку функции sin вместе со средними точками интегральных интервалов:

df <- data.frame(Lower = c(1,2,3), Upper = c(2,3,4))
setDT(df)
getIntegral <- function(l, u) {
  n <- integrate(sin, mean(l), mean(u))
  list(Value=n$value, Error=n$abs.error)
}
df[,
   c('Value', 'Error', 'Mid') := {
     n <- getIntegral(Lower, Upper)
     list(n$Value,
          n$Error,
          (Lower+Upper)/2)
   }]
df
   Lower Upper     Value        Error Mid
1:     1     2 0.5738457 6.370967e-15 1.5
2:     2     3 0.5738457 6.370967e-15 2.5
3:     3     4 0.5738457 6.370967e-15 3.5

Мне не нравится мой подход, потому что разделение имен новых столбцов и назначенных им значений затрудняет чтение, как я могу сделать эту задачу лучше? Это часть длинной цепочки обработки данных, поэтому я не хочу создавать временную переменную снаружи, поэтому предпочитаю использовать решения только с помощью data.table или dplyr.

Ответ 1

RHS должен быть списком значений, и каждый элемент списка преобразуется в столбец (и при необходимости перерабатывается).

Ваша функция уже возвращает list (длиной 1 каждый), а (Lower+Upper)/2 возвращает вектор из 3 значений (здесь). Чтобы вернуть список, вы можете использовать функцию c() следующим образом:

df[, c('Value', 'Error', 'Mid') := c(getIntegral(Lower, Upper), list((Lower+Upper)/2))]
#    Lower Upper     Value        Error Mid
# 1:     1     2 0.5738457 6.370967e-15 1.5
# 2:     2     3 0.5738457 6.370967e-15 2.5
# 3:     3     4 0.5738457 6.370967e-15 3.5

Это использует тот факт, что c(list, list) приводит к объединенному списку.