检查数据帧 Rcpp 中的布尔表达式 (C++)

check boolean expression in dataframe 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 做到这一点?

这里值得强调的两件事是

  • 你不需要所有行都低,因为 R 是矢量化的,而且已经很快了

  • 您可以将规则扫过您的数据并return一个结果矩阵

两者都是 one-liner:

> 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)。)

因为这已经是矢量化的,所以它会比您的 per-row 调用更快,即使您使用 Rcpp 执行它也不会比已经矢量化的代码快(很多)。