I have a function that checks for the presence of logical sequences in a dataframe
fu <- function(dat , rule , res.only=T){
debug.vec <- rep("no",nrow(dat)) # control of rule triggers
rule.id <- 1 # rule number in vector
for(i in 1:nrow(dat)){
# check if the rule "rule[rule.id]" has worked on this "i" index in dat[i,]
current_rule <- with(data = dat[i,] , expr = eval(parse(text = rule[rule.id])) )
if(current_rule){ # if the rule is triggered
debug.vec[i] <- rule[rule.id]
if( rule.id==length(rule) ) break # stop if there are no more rules
rule.id <- rule.id+1 # go to the next rule
}}
if(!res.only) return( cbind(dat,debug.vec) )
return( sum(debug.vec!="no")==length(rule) )
}
for example i have some data
set.seed(123)
dat <- as.data.frame(matrix(data = sample(10,30,replace = T),ncol = 3))
colnames(dat) <- paste0("x" ,1:ncol(dat))
..
dat
x1 x2 x3
1 3 5 9
2 3 3 3
3 10 9 4
4 2 9 1
5 6 9 7
6 5 3 5
7 4 8 10
8 6 10 7
9 9 7 9
10 10 10 9
there is also a vector with rules
rule <- c("x1>5 & x2>2" , "x1>x2" , "x3!=4" )
the function checks if there is such a logical sequence in the dataframe and gives a logical answer
> fu(dat = dat, rule = rule, res.only = T)
[1] TRUE
or you can change the flag res.only = F and see where the sequence was in the debug.vec column
> fu(dat = dat, rule = rule, res.only = F)
x1 x2 x3 debug.vec
1 3 5 9 no
2 3 3 3 no
3 10 9 4 x1>5 & x2>2
4 2 9 1 no
5 6 9 7 no
6 5 3 5 x1>x2
7 4 8 10 x3!=4
8 6 10 7 no
9 9 7 9 no
10 10 10 9 no
I need the fastest possible version of this function, perhaps using the Rccp package or something like that..
UPD=======================
the Waldi function is not working identically to my function, something is wrong
UPD_2_====================================
# Is this correct?
Yes, this is correct if the rule[k] is triggered then the search for rule[k+1] starts with a new row of dat
forgive me for not being precise enough in my question, this is my fault
my function returned FALSE because the last rule "x3!=4" did not work, it should be
dat <- structure(list(x1 = c(2L, 5L, 1L, 3L, 9L, 2L, 6L, 3L, 3L, 9L),
x2 = c(2L, 1L, 6L, 10L, 8L, 10L, 10L, 4L, 6L, 4L),
x3 = c(4L, 9L, 8L, 7L, 10L, 1L, 2L, 8L, 3L, 10L)),
class = "data.frame", row.names = c(NA, -10L))
dat
rule <- c("x1>5 & x2>2" , "x1>x2" , "x3!=4" )
my_fu(dat = dat, rule = rule, res.only = F)
only two rules worked
> my_fu(dat = dat, rule = rule, res.only = F)
x1 x2 x3 debug.vec
1 2 2 4 no
2 5 1 9 no
3 1 6 8 no
4 3 10 7 no
5 9 8 10 x1>5 & x2>2
6 2 10 1 no
7 6 10 2 no
8 3 4 8 no
9 3 6 3 no
10 9 4 10 x1>x2
it should be
> my_fu(dat = dat, rule = rule, res.only = T)
[1] FALSE