mika
mika

Reputation: 23

How to test whether each element in a column of values falls between values in two other columns?

This may be a very convoluted way of asking this question. I have a column of "results" that I want to test against statistics of previous results, namely calculated minimum and maximum values. If the value in the result column falls between the corresponding min and max values, I want to assign it as "1" in a fourth column named Within_range and if not, "0". I have tried using relational operators (<,>)

df$Within_Range <- if(df$Result > df$Min & df$Result < df$Max){"1"} else {"0"}

and got this: In if (df$Result > df$Min & df$Result < df$Max) { : the condition has length > 1 and only the first element will be used

R did not seem to like that I tried to use multiple conditions, so I tried using between()

df$Within_Range <- if(between(df$Result,df$Min,df$Max)){"1"} else {"0"}

and I got this: Error: Expecting a single value: [extent=20511].

Here is some example code:

Result <- 1:5
Min <- c(2,1,2,3,4)
Max <- c(3,4,5,8,7)
df <- data.frame(Result, Min, Max)

Apologies if this is a silly question; I am still new to R and hours of searching R forums returned nothing helpful... I am stuck.

Upvotes: 1

Views: 292

Answers (2)

Jason Mathews
Jason Mathews

Reputation: 805

df %>% mutate(Within_Range = between(Result, Min, Max))

## OutPut
  Result Min Max Within_Range
1      1   2   3        FALSE
2      2   1   4         TRUE
3      3   2   5         TRUE
4      4   3   8         TRUE
5      5   4   7         TRUE

Upvotes: 0

akrun
akrun

Reputation: 887213

between is not vectorized for the left, right arguments. We need comparison operators

df$Within_Range <- with(df, +(Result > Min & Result < Max))

NOTE: Change to >= or <= if the range should also include the Min, Max values


Also, in the first piece of code, the if/else is unnecessary due to multiple reasons

  1. It is not vectorized i.e. it expects a input of length 1 and output a logical vector of length 1 (df$Result and other columns are obviously having length greater than 1)
  2. TRUE/FALSE output from comparison operators are stored as 1/0 values. So, we just need to coerce it to binary with as.integer or +

Upvotes: 1

Related Questions