Проверить логическое выражение в фрейме данных Rcpp (C++)

У меня есть датафрейм dat с данными и вектор rule с логическими правилами

set.seed(124)
ro <- round(runif(n = 30,1,10),2)
dat <- as.data.frame(matrix(data =ro,ncol = 3)) ; colnames(dat) <- paste0("x" ,1:ncol(dat))
rule <- c("x1 > 5 & x2/2 > 2"  ,  "x1 > x2*2"  ,  "x3!=4")

Мне нужно проверить, верно ли выражение

id <- 2
 for(i in 1:nrow(dat)){
   cr <- with(data = dat[i,] , expr = eval(parse(text = rule[id])))
   print(cr)
 }
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] TRUE
[1] FALSE
[1] FALSE
[1] FALSE
[1] TRUE

Как это сделать с помощью Rcpp ?

Это не очень корректный вопрос. Вы полагаетесь на eval() здесь: где / как у Rcpp есть что-то эквивалентное? Это невозможно, поэтому вы в конечном итоге вызовете eval() в R из C++. Конечно, существует множество способов построить дерево решений на основе описания. Но они не однострочные. (Кроме того, чего бы это ни стоило, даже с вашим семенем я получаю with(dat, x1 > 5 & x2/2 > 2 & x1 > x2*2 & x3 != 4) возврат всех FALSE.

Dirk Eddelbuettel 06.04.2022 17:06

Привет, спасибо за ответ, Смотри внимательно, здесь три правила, а не одно

mr.T 06.04.2022 17:20

Будь то одно правило из трех или одно из трех, ваша проблема более глубока, как я пытался объяснить. eval() очень нужен переводчик. Rcpp не отправляет его, он может вызывать только R или компилировать код, используя непосредственно компилируемые выражения.

Dirk Eddelbuettel 06.04.2022 18:52
Получение данных из формы с помощью JavaScript - краткое руководство
Получение данных из формы с помощью JavaScript - краткое руководство
Получить данные из формы с помощью JS очень просто: вы запрашиваете элемент формы, передаете его конструктору new FormData() и, наконец, получаете...
Пользовательские правила валидации в Laravel
Пользовательские правила валидации в Laravel
Если вы хотите создать свое собственное правило валидации, Laravel предоставляет возможность сделать это. Создайте правило с помощью следующей...
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
0
3
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь стоит подчеркнуть две вещи:

  • вам не нужен низкий уровень по всем строкам, так как R векторизован, и это уже быстро

  • вы можете применить правила к своим данным и вернуть результирующую матрицу

Оба они являются однострочными:

> res <- do.call(cbind, lapply(rule, \(r) with(dat, eval(parse(text=r)))))
> res
       [,1]  [,2] [,3]
 [1,] FALSE FALSE TRUE
 [2,] FALSE FALSE TRUE
 [3,]  TRUE FALSE TRUE
 [4,] FALSE FALSE TRUE
 [5,] FALSE FALSE TRUE
 [6,] FALSE  TRUE TRUE
 [7,]  TRUE FALSE TRUE
 [8,]  TRUE FALSE TRUE
 [9,]  TRUE FALSE TRUE
[10,] FALSE  TRUE TRUE
> 

(Я использовал там анонимную функцию R 4.1.*, вы также можете заменить \(r) на стандартную function(r).)

Поскольку это уже векторизовано, это будет быстрее, чем ваш вызов для каждой строки, и даже если вы сделали это с Rcpp, if не будет (намного) быстрее, чем уже векторизованный код.

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