Квазиквотация с таблицей данных - PullRequest
2 голосов
/ 21 октября 2019

Я пытаюсь обернуть голову квази-цитатой, чтобы я мог использовать ее вместе с data.table вызовом. Вот пример:

library(data.table)
library(rlang)
dt <- data.table(col1 = 1:10, col2 = 11:20)

dt[, col1]

Если бы я хотел обернуть это в функцию, как бы я это сделал? Я попробовал:

foo <- function(dt, col) {
  col <- quo(col)

  expr(dt[, !!col1])
}

foo(dt, col1)

Но получилось Error in enexpr(expr) : object 'col1' not found. Я предполагаю, что пропускаю некоторые шаги, поскольку data.table оценивает это иначе, чем dplyr.

Ответы [ 2 ]

5 голосов
/ 21 октября 2019

Вы хотите захватить имя столбца как символ с

col <- ensym(col)

вместо quo() и затем использовать

expr(dt[, !!col])

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

eval_tidy(expr(dt[, !!col]))

Но на самом деле квазинотация лучше всего работает в тидиверсе, а не с функциями data.table. Способ «data.table» может быть больше похож на что-то в этом существующем вопросе: Передать имя столбца в data.table, используя переменную . data.table очень предпочитает строки символам.

1 голос
/ 21 октября 2019

Вы можете использовать deparse и substitute и использовать аргумент with=FALSE как в:

foo <- function(dt, col){
  col_str = deparse(substitute(col))
  dt[, col_str, with = F]
}

или вы можете использовать eval и substitute и использовать таблицу данных по умолчанию. аргумент with=TRUE как в:

foo <- function(dt, col){
  col_symb = substitute(col)
  dt[, eval(col_symb)] # by default: with=TRUE
}

В обоих случаях substitute получит имя аргумента, передаваемого параметру col. В первом случае deparse преобразует это имя в строку, что позволяет нам выбрать его из таблицы данных, используя with = FALSE. Во втором случае мы оцениваем (используя eval) имя аргумента в контексте data.table.

...