Можно ли заменить элемент `i` в data.table[i, j, by]

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

Если это невозможно, я приветствую любые идеи альтернативных решений.

Базовый пример

library(data.table)

dt = data.table(
  y = rep(c('a','b'),5),
  x = 1:10
)

exp1 = "x > 5"

dt[y == "a" & substitute(exp1)]
# Error: operations are possible only for numeric, logical or complex types

Не используйте анализ eval. Используйте новый аргумент env в data.table, который был создан именно для решения таких проблем, как ваша. Подробнее об этом можно прочитать в новой виньетке rdatatable.gitlab.io/data.table/articles/…

jangorecki 29.04.2023 06:43

@jangorecki новый аргумент env в настоящее время доступен только в версии для разработчиков. В CRAN-версии 1.14.8 этой функции еще не было.

Hieu Nguyen 29.04.2023 07:39

Да, я знаю, просто запустите data.table::update_dev_pkg()

jangorecki 29.04.2023 12:16

@jangorecki - я знаю о новом аргументе env и хочу, чтобы это был жизнеспособный вариант. Тем не менее, блестящее приложение, над которым я работаю, является частью большой группы приложений, управляемых одной и той же renv настройкой. Поэтому я очень осторожно отношусь к использованию версии dev любого пакета в производстве.

Jamie 01.05.2023 16:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
4
130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Можно использовать eval(parse(..)), но есть некоторые проблемы, связанные с этим.

library(data.table)

exp1 = "x > 5"
dt[y == "a" & eval(parse(text = exp1))]

#   y x
#1: a 7
#2: a 9

у eval(str2lang(expr1)) тоже есть проблемы? или даже eval(str2expression(expr1))

Onyambu 29.04.2023 03:26

Хм ... Я не использовал их, поэтому я не уверен.

Ronak Shah 29.04.2023 03:50

@Onyambu eval(parse(..)), eval(str2lang(expr1)) и eval(str2expression(expr1)) требуют, чтобы выражения строились путем манипуляций со строками (объединение, замена...), а затем анализировались. У авторов data.table есть довольно хорошее резюме о его проблемах.

Hieu Nguyen 29.04.2023 08:28
Ответ принят как подходящий

Мой подход таков:

library(data.table)
exp1 = "x > 5" |> str2lang()
(ll <- substitute(
    dt[y == "a" & e1],
    list(
        e1 = exp1
    )
))
eval(ll)

Я думаю, что это хороший подход, потому что он поддерживает идиоматический вид data.table. Например, если вы хотите dt[y == "a" & x > 5, .(mm = length(x)), by = "y"]:

(ll <- substitute(
    dt[y == "a" & e1, .(mm = f1(e2)), by = e3], # Change right here and maintain data.table's look
    list(
        e1 = exp1,
        # e1 = "x > 5" |> str2lang(),
        e2 = quote(x), # Allow more flexibilities
        e3 = "y", # Allow more flexibilities
        f1 = quote(length) # Allow more flexibilities
    )
))
eval(ll)

Это также похоже на подходы substitute2 и env, предложенные в разрабатываемой версии data.table.

Да, env arg просто оборачивает i, j, by в подстановочные вызовы

jangorecki 29.04.2023 14:08

Потрясающе, спасибо за это! Не могли бы вы объяснить во втором примере необходимость добавления quote вместо e2 и f1. Или отошлите меня к какой-нибудь документации по этому поводу?

Jamie 01.05.2023 17:25

@ Джейми Извините за поздний ответ. Без quote в e2 оно станет e2 = x. Это станет случаем e1 (т. Е. Найдите где-нибудь эту переменную x и подставьте значение переменной x в e2). Попробуйте x <- 3; (ll <- substitute(dt[y == "a" & e1, .(mm = f1(e2)), by = e3], list(e1 = "x > 5" |> str2lang(), e2 = x, e3 = "y", f1 = quote(length)))), результат dt[y == "a" & x > 5, .(mm = length(3)), by = "y"]

Hieu Nguyen 20.05.2023 14:31

Кроме того, вы можете использовать e2 = as.name("x") вместо e2 = quote(x). В этом случае облегчает интерпретацию то, что нам нужно имя/символ x, а не значение x.

Hieu Nguyen 20.05.2023 14:41

Канонические ресурсы для этого: Руководства по R-Определение языка R-Вычисления на языке и help(quote), help(expression), help(parse)...

Hieu Nguyen 20.05.2023 15:14

Другие вопросы по теме