Как преобразовать объект r data.table на основе параметра функции - PullRequest
0 голосов
/ 15 декабря 2018

Я хотел бы создать функцию r, которая принимает 2 параметра:

  1. объект data.table
  2. инструкция о том, как добавить новые столбцы в таблицу данных.Эти новые столбцы являются преобразованием уже существующих столбцов.

Без функции переноса я мог бы сделать:

# load data.table library
library(data.table)
# the exsample data set
dt <- data.table(mtcars)

# adding some new columns
dt[, `:=`(disp_plus_hp = disp + hp,
          drat_plus_wt = drat + wt)]

Я знаю, что могуиспользуйте комбо eval + parse, чтобы решить мою проблему следующим образом:

# load the exsample data set
dt <- data.table(mtcars)

# character vector of length 1 specifying the transformation
column_transformation = '`:=`(disp_plus_hp = disp + hp,
                              drat_plus_wt = drat + wt)'

# define a function that takes data table and the above character
# to transform the data table
dt_transformer <- function(data_table, add_columns)
{
  data_table[, eval(parse(text = add_columns))]
}

# equivalent to dt[, `:=`(disp_plus_hp = disp + hp,drat_plus_wt = drat + wt)]
dt_transformer(data_table = dt, add_columns = column_transformation)

Теперь есть две причины, по которым я хотел бы улучшить решение:

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

1 Ответ

0 голосов
/ 15 декабря 2018

В основном вам нужна функция dplyr::mutate, но с оператором :=.Я рекомендую вам прочитать главу нестандартная оценка из книги Advanced R.Следующая функция должна быть улучшена, но в основном выполняет ту работу, которую вы хотите.

dtmutate <- function(dt, ...)
{
  exprs <- lazyeval::dots_capture(...)

  for (i in seq_along(exprs))
  {    
    col  <- names(exprs)[i]
    expr <- exprs[[i]]
    val  <- lazyeval::f_eval(expr, dt)
    dt[, (col) := val]
  }

  dt[]
  return(invisible())
}

library(data.table)
dt <- data.table(a = 1:10, b = 1:10*2)
dtmutate(dt = dt, c = a+b, d = a*b)
dt
...