简体   繁体   中英

R if else statement multiple conditions

I'm trying to develop an if else statement to apply to my data.frame below. These are the conditions I'm trying to account for:

  1. If the year in "Year" is = or > the larger year value in "YearLimitA" or "YearLimitB", then the value in "Value" stays the same.
  2. If the year in "Year" is < one of the year values in either "YearLimitA" or "YearLimitB", but > or = to the other year value in "YearLimitA" or "YearLimitB", the the value in "Value" needs to be divided by 2.
  3. If the year in "Year" is < both year values in "YearLimitA" and "YearLimitB", then the value in "Value" (and really the whole row) should be removed.

If you have any thoughts on the best way to do this, I would really appreciate it. I'm not sure where to start when there are multiple conditions.

Example df:

Name <- c("t1", "t1", "t1", "t1", "t2", "t2", "t2", "t3", "t3", "t3", "t3")
Value <- c(1.7, 2.6, 3.2, 4.1, 1.8, 3.4, 2.4, 3.6, 4.0, 1.9, 2.3)
Year <- c(2000, 2001, 2002, 2003, 2001, 2002, 2003, 2000, 2001, 2002, 2003)
YearLimitA <- c(2001, 2001, 2001, 2001, 2002, 2002, 2002, 2002, 2002, 2002, 2002)
YearLimitB <- c(2002, 2002, 2002, 2002, 2002, 2002, 2002, 2001, 2001, 2001, 2001)
df <- data.frame(Name, Value, Year, YearLimitA, YearLimitB)

Intended df after if else statement:

Name <- c("t1", "t1", "t1", "t2", "t2", "t3", "t3", "t3")
Value <- c(1.3, 3.2, 4.1, 3.4, 2.4, 2.0, 1.9, 2.3)
Year <- c(2001, 2002, 2003, 2002, 2003, 2001, 2002, 2003)
YearLimitA <- c(2001, 2001, 2001, 2002, 2002, 2002, 2002, 2002)
YearLimitB <- c(2002, 2002, 2002, 2002, 2002, 2001, 2001, 2001)
df2 <- data.frame(Name, Value, Year, YearLimitA, YearLimitB)

Try this:

 df <- df[df$Year >= pmin(df$YearLimitA, df$YearLimitB),]
 df$Value <- with(df, ifelse(Year>=pmax(YearLimitA, YearLimitB), Value, Value/2))

First, we only keep rows in which Year is at least as big as the minimum of YearLimitA and YearLimitB . Then, if Year is at least as big as the pairwise maximum of those two variables, then the value is retained. If not, it is divided by 2.

This yields

    Name Value Year YearLimitA YearLimitB
 2    t1   1.3 2001       2001       2002
 3    t1   3.2 2002       2001       2002
 4    t1   4.1 2003       2001       2002
 6    t2   3.4 2002       2002       2002
 7    t2   2.4 2003       2002       2002
 9    t3   2.0 2001       2002       2001
 10   t3   1.9 2002       2002       2001
 11   t3   2.3 2003       2002       2001

and all.equal(df2, df, check.attributes=F) gives TRUE .

Here's one approach:

# sort years
rangeYear <- apply(df[c("YearLimitA", "YearLimitB")], 1, range)
# remove colums
idx <- df$Year >= rangeYear[1, ]
df2 <- df[idx, ]
# change values
df2 <- transform(df2, Value = Value / (1 + (Year < rangeYear[2, ][idx])))

The result:

   Name Value Year YearLimitA YearLimitB
2    t1   1.3 2001       2001       2002
3    t1   3.2 2002       2001       2002
4    t1   4.1 2003       2001       2002
6    t2   3.4 2002       2002       2002
7    t2   2.4 2003       2002       2002
9    t3   2.0 2001       2002       2001
10   t3   1.9 2002       2002       2001
11   t3   2.3 2003       2002       2001

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM