Nano Hash - криптовалюты, майнинг, программирование

Простой воспроизводимый пример передачи аргументов в data.table в самоопределяемой функции в R.

Я гуглил этот ответ в течение нескольких часов. Многие люди задавали подобные вопросы, но я не нашел ни достаточно простого вопроса, ни прямого ответа. Вот мой подход:

Предположим, что я хочу сделать простую группу в data.table:

library(data.table)
mtcars = data.table(mtcars)
mtcars[,sum(mpg), gear]

# Here are the results
#   gear    V1
#1:    4 294.4
#2:    3 241.6
#3:    5 106.9

Однако, если я использую для этого самоопределяемую функцию:

zz = function(data, var, group){
  return(data[,sum(var), group])
}
zz(mtcars, mpg, gear)

Я получил сообщение об ошибке:

Ошибка в eval (bysub, parent.frame(), parent.frame()): объект «шестерня» не найден

Я пробовал substitute, eval, quote и другие решения, но ни одно из них не работает. Интересно, может ли кто-нибудь дать более простое решение и объяснение этому.

Спасибо и счастливого Хэллоуина!

31.10.2019

Ответы:


1

Если мы используем аргументы без кавычек, substitute и evaluate

zz <- function(data, var, group){
 var <- substitute(var)
 group <- substitute(group)
 setnames(data[, sum(eval(var)), by = group],
        c(deparse(group), deparse(var)))[]
 # or use
 #  setnames(data[, sum(eval(var)), by = c(deparse(group))], 2, deparse(var))[]

}
zz(mtcars, mpg, gear)
#   gear   mpg
#1:    4 294.4
#2:    3 241.6
#3:    5 106.9
31.10.2019
  • @Грегор Я предполагаю, что это может быть связано с env substitute(expr, env), поскольку substitute будет проверять переменные в окружении таблицы данных. Можете ли вы попробовать, изменив env 31.10.2019
  • Это имеет смысл, но после того, как я немного поиграл, я все еще не заставляю его работать. Думаю, придется задать вопрос... 31.10.2019
  • @Грегор, я тоже пробовал. Я помню подобный вопрос раньше, но не мог узнать. Пожалуйста, задайте вопрос. Спасибо 31.10.2019
  • Спасибо за быстрый ответ! У меня тот же вопрос, что и у @Gregor. Не могли бы вы также опубликовать свой вопрос в комментарии к этому вопросу? 31.10.2019
  • Новый вопрос здесь: stackoverflow.com/q/58649510/903061 (теперь мне жаль, что я не удалил исходный комментарий ) 31.10.2019
  • @Грегор Спасибо! 01.11.2019

  • 2

    Хотя это и не идеально, аргумент ... может быть полезен:

    zz = function(dt, ...){
      return(dt[...])
    }
    
    zz(mtcars, , sum(mpg), gear)
    
       gear    V1
    1:    4 294.4
    2:    3 241.6
    3:    5 106.9
    
    31.10.2019

    3

    Я не вижу смысла писать функцию, которая принимает аргументы без кавычек. Почему бы просто не использовать синтаксис data.table напрямую?

    Если вы хотите написать функцию, имеет смысл взять вектор символов имен столбцов, так как это гораздо более программируемо, чем символы (подумайте о программировании с setkey по сравнению с setkeyv или написании функций для создания ggplots с aes по сравнению с aes_string ). Недостатком является то, что внутренняя часть функции запутана и требует eval(parse(text=.))) NSE для правильной работы GForce, но интерфейс функции более расширяемый.

    zz = function(data, var, group){
      eval(parse(text=paste0("data[,sum(",var,"),by=",group,"]")))
    }
    zz(mtcars, "mpg", "gear")
    
    21.02.2020
  • Эй, Майкл! Определенно интересный подход. Я не пишу много подобных функций, но я определенно вижу привлекательность аргументов без кавычек для интерактивного использования, особенно с завершением с помощью табуляции. eval-parse-paste все еще чувствует себя плохо для меня, хотя я не могу определить какой-либо конкретный риск в этом случае. 24.02.2020
  • Мне потребовалось некоторое время, чтобы остановиться на этом. Я видел, как Мэтт Доул рекомендовал этот подход (думаю, он называл это макросом), и это сделало меня немного более уверенным в том, что это хороший способ. Я считаю, что Мэтт потратил много времени на программирование SQL, которое в значительной степени зависит от программирования макросов в форме процедур, что, возможно, объясняет, почему он рекомендует этот подход к написанию функций вокруг data.table. 24.02.2020
  • Строки без кавычек отлично подходят для интерактивных сценариев, но, как я уже сказал, в этом случае я бы придерживался прямого использования интерфейса data.table, так как позже он будет более читабельным для меня или для других, которые хорошо разбираются в data.table. Синтаксис data.table настолько лаконичен, что не стоит скрывать его даже для часто используемых операций. Вышеупомянутый подход, я думаю, больше подходит для сложных многократно используемых процедур в конвейерах данных (например, замена процедур sql). 24.02.2020
  • Я добавлю, что, насколько мне известно, это самый простой (единственный?) способ программного использования data.table для произвольных имен столбцов таким образом, чтобы не нарушать оптимизацию. (это, возможно, частично основано на моем определении произвольного - я не считаю символ произвольным именем столбца, поскольку это языковой объект, а не вектор. Мой подход скрывает и завершает NSE по сравнению с функцией, принимающей строку без кавычек, создает бремя на пользователя, чтобы сделать больше, чтобы запрограммировать эту функцию, чтобы использовать ее программно). Но если есть другой способ использовать строки в кавычках, я бы хотел это услышать 24.02.2020
  • Что ж, аргумент by может быть строкой в ​​кавычках --- либо вектором символов имен столбцов, либо вектором длины один символ имен, разделенных запятыми, но я думаю, что вы правы насчет j, использование .SDcols (я думаю) меньше эффективный. Тем не менее, x = c("mpg", "hp"), g = c("am", "cyl"), затем mtcars[, lapply(.SD, mean), by = g, .SDcols = g) писать довольно приятно. Но, конечно, не так гибко, как позволить пользователю вводить произвольную строку. 24.02.2020
  • Между тем, akrun только что ответил на этот вопрос, когда я набирал этот комментарий... 24.02.2020
  • Да, подход .SD - это тот, с которым я тоже экспериментировал, и он почти соответствует моим критериям произвольного программирования (он не работает в операторе i, и вам нужно сделать некоторые другие трюки, чтобы получить произвольные имена столбцов в назначении LHS). В конечном итоге я остановился на подходе .SD для программирования, потому что он требует отслеживания индексов .SD, которые мне было трудно отслеживать для сложных операторов j (даже в большей степени, чем макросы, которые, по крайней мере, можно отладить, оценив вставку, чтобы получить очень читаемый синтаксис data.table) 24.02.2020
  • Например, может быть непросто отдельно и многократно, например, взять произведение между столбцом 1 таблицы данных и произвольным количеством других столбцов без использования какой-либо привередливой индексации .SD в сочетании с лапароскопией. 24.02.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..