Используйте строковое представление переменной в i для data.table - PullRequest
1 голос
/ 25 мая 2020

По-видимому, я слишком глуп, чтобы ввести правильные условия поиска, b / c Я думаю, что мой вопрос вовсе не уникален.

Как ссылаться на переменную по строке в i части data.table? with и ..x подходят для части j, но какой будет эквивалент в части i? Должен ли я использовать зло eval (каламбур;)

library(data.table)
dt <- data.table(x = 1:4, y = 4:1)

my_filter_fun <- function(var = names(dt)) {
  var <- match.arg(var)
  dt[eval(parse(text = paste(var, "== 1")))]
}
my_filter_fun("x")
my_filter_fun("y")

Какой идиоматический c способ в data.table делать это? Исходя из dplyr Я думаю, что ищу эквивалент запросов для data.table?

Бонусный вопрос: как я могу реализовать my_filter_fun, чтобы такой вызов

my_filter_fun(x > 1)

вернет тот же результат, что и

dt[x > 1]

Ответы [ 2 ]

2 голосов
/ 26 мая 2020

Для вашего первого вопроса я предлагаю использовать get(), чтобы избежать зла eval():

my_filter_fun <- function(var = names(dt)) {
  var <- match.arg(var)
  dt[get(var) == 1]
}
my_filter_fun("x")
   x y
1: 1 4

Что касается бонусного вопроса, вы могли бы сделать следующее. Возможно, это можно упростить - просто я не знаю, как.

bonus_filter_fun <- function(filter) {
  filter <- deparse(substitute(filter))
  dt[eval(parse(text = filter))]
}
bonus_filter_fun(x > 1)
   x y
1: 2 3
2: 3 2
3: 4 1
0 голосов
/ 25 мая 2020

Вы должны использовать esoteri c R magi c, но не eval. Вы спрашиваете о NSE или нестандартной оценке. Вот пример, похожий на ваш:

theDf <- tibble(Sticks = 4:7, Stones = 9:12)
#' @title Create a new column by adding 8 to one of the existing columns.
a8Col <- function(df, newName, existName){
  existName <- enquo(existName)
  df %>%
    mutate(!! newName := !! existName + 8L )
}

R > a8Col(theDf, "Bones", Sticks)
# A tibble: 4 x 3
Sticks Stones Bones
<int>  <int> <int>
1      4      9    12
2      5     10    13
3      6     11    14
4      7     12    15
R > a8Col(theDf, "Bones", Stones)
# A tibble: 4 x 3
Sticks Stones Bones
<int>  <int> <int>
1      4      9    17
2      5     10    18
3      6     11    19
4      7     12    20

Обратите внимание, что мне не нужно ставить кавычки вокруг Sticks или Stones при вызовах a8Col.

NSE - это жесткий топи c. Хэдли Уикхэм написал об этом две главы (Quasiquotation и Evaluation) в своей книге « Advanced R ».

...