8

I have a data.frame like this:

 value condition 1 0.46 value > 0.5 2 0.96 value == 0.79 3 0.45 value <= 0.65 4 0.68 value == 0.88 5 0.57 value < 0.9 6 0.10 value > 0.01 7 0.90 value >= 0.6 8 0.25 value < 0.91 9 0.04 value > 0.2 structure(list(value = c(0.46, 0.96, 0.45, 0.68, 0.57, 0.1, 0.9, 0.25, 0.04), condition = c("value > 0.5", "value == 0.79", "value <= 0.65", "value == 0.88", "value < 0.9", "value > 0.01", "value >= 0.6", "value < 0.91", "value > 0.2")), class = "data.frame", row.names = c(NA, -9L)) 

I would like to evaluate the strings in the condition column for every row.

So the result would look like this.

 value condition goal 1 0.46 value > 0.5 FALSE 2 0.96 value == 0.79 FALSE 3 0.45 value <= 0.65 TRUE 4 0.68 value == 0.88 FALSE 5 0.57 value < 0.9 TRUE 6 0.10 value > 0.01 TRUE 7 0.90 value >= 0.6 TRUE 8 0.25 value < 0.91 TRUE 9 0.04 value > 0.2 FALSE 

I suppose there is a handy NSE solution within the dplyr framework. I have experimented with !! and expr() and others. I got some promising results when trying to subset by condition using

result <- df[0,] for(i in 1:nrow(df)) { result <- rbind(result, filter_(df[i,], bquote(.(df$condition[i])))) } 

But I don't like the solution and it's not exactly what I'm after.

I hope someone can help.

UPDATE: I'm trying to avoid eval(parse(..)).

4 Answers 4

5

Not entirely sure whether you are looking for something like this, however, you can also use lazy_eval() from lazyeval:

df %>% rowwise() %>% mutate(res = lazy_eval(sub("value", value, condition))) value condition res <dbl> <chr> <lgl> 1 0.46 value > 0.5 FALSE 2 0.96 value == 0.79 FALSE 3 0.45 value <= 0.65 TRUE 4 0.68 value == 0.88 FALSE 5 0.570 value < 0.9 TRUE 6 0.1 value > 0.01 TRUE 7 0.9 value >= 0.6 TRUE 8 0.25 value < 0.91 TRUE 9 0.04 value > 0.2 FALSE 

And even though it is very close to eval(parse(...)), a possibility is also using parse_expr() from rlang:

df %>% rowwise() %>% mutate(res = eval(rlang::parse_expr(condition))) 
Sign up to request clarification or add additional context in comments.

Comments

5

One straightforward and easy solution would be using eval(parse...

library(dplyr) df %>% rowwise() %>% mutate(goal = eval(parse(text = condition))) # A tibble: 9 x 3 # value condition goal # <dbl> <chr> <lgl> #1 0.46 value > 0.5 FALSE #2 0.96 value == 0.79 FALSE #3 0.45 value <= 0.65 TRUE #4 0.68 value == 0.88 FALSE #5 0.570 value < 0.9 TRUE #6 0.1 value > 0.01 TRUE #7 0.9 value >= 0.6 TRUE #8 0.25 value < 0.91 TRUE #9 0.04 value > 0.2 FALSE 

However, I would recommend reading some posts before using it.

1 Comment

That's true of course, I know eval(parse(..)) but I try to find a solution without it using NSE in dplyr. I should have been more specific about it.
3

Using match.fun:

# get function, and the value myFun <- lapply(strsplit(df1$condition, " "), function(i){ list(f = match.fun(i[ 2 ]), v = as.numeric(i[ 3 ])) }) df1$goal <- mapply(function(x, y){ x[[ "f" ]](y, x[ "v" ]) }, x = myFun, y = df1$value) # value condition goal # 1 0.46 value > 0.5 FALSE # 2 0.96 value == 0.79 FALSE # 3 0.45 value <= 0.65 TRUE # 4 0.68 value == 0.88 FALSE # 5 0.57 value < 0.9 TRUE # 6 0.10 value > 0.01 TRUE # 7 0.90 value >= 0.6 TRUE # 8 0.25 value < 0.91 TRUE # 9 0.04 value > 0.2 FALSE 

Comments

2

If you want to avoid eval(parse... you can try this:

library(tidyverse) df %>% mutate(bound = as.numeric(str_extract(condition, "[0-9 \\.]*$")), goal = case_when(grepl("==", condition) ~ value == bound, grepl(">=", condition) ~ value >= bound, grepl("<=", condition) ~ value <= bound, grepl(">", condition) ~ value > bound, grepl("<", condition) ~ value < bound, T ~ NA)) value condition bound goal 1 0.46 value > 0.5 0.50 FALSE 2 0.96 value == 0.79 0.79 FALSE 3 0.45 value <= 0.65 0.65 TRUE 4 0.68 value == 0.88 0.88 FALSE 5 0.57 value < 0.9 0.90 TRUE 6 0.10 value > 0.01 0.01 TRUE 7 0.90 value >= 0.6 0.60 TRUE 8 0.25 value < 0.91 0.91 TRUE 9 0.04 value > 0.2 0.20 FALSE 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.