Geogrammer Geogrammer - 2 months ago 5
R Question

Getting a dataframe of logical values from a vector of statements

I have a number of lists of conditions and I would like to evaluate their combinations, and then I'd like to get binary values for these logical values (True = 1, False = 0). The conditions themselves may change or grow as my project progresses, and so I'd like to have one place within the script where I can alter these conditional statements, while the rest of the script stays the same.

Here is a simplified, reproducible example:

# get the data
df <- data.frame(id = c(1,2,3,4,5), x = c(11,4,8,9,12), y = c(0.5,0.9,0.11,0.6, 0.5))

# name and define the conditions
names1 <- c("above2","above5")
conditions1 <- c("df$x > 2", "df$x >5")

names2 <- c("belowpt6", "belowpt4")
conditions2 <- c("df$y < 0.6", "df$y < 0.4")

# create an object that contains the unique combinations of these conditions and their names, to be used for labeling columns later

names_combinations <- as.vector(t(outer(names1, names2, paste, sep="_")))

condition_combinations <- as.vector(t(outer(conditions1, conditions2, paste, sep=" & ")))

# create a dataframe of the logical values of these conditions

condition_combinations_logical <- ????? # This is where I need help

# lapply to get binary values from these logical vectors

df[paste0("var_",names_combinations] <- +(condition_combinations_logical)


to get output that could look something like:

-id -- | -x -- | -y -- | -var_above2_belowpt6 -- | -var_above2_belowpt4 -- | etc.
1 | 11 | 0.5 | 1 | 0 |
2 | 4 | 0.9 | 0 | 0 |
3 | 8 | 0.11 | 1 | 1 |
etc. ....

Answer

Looks like the dreaded eval(parse()) does it (hard to think of a much easier way ...). Then use storage.mode()<- to convert from logical to integer ...

res <- sapply(condition_combinations,function(x) eval(parse(text=x)))
storage.mode(res) <- "integer"
Comments