Reputation: 534
Here is my code:
library(lubridate)
library(tidyverse)
day <- c("20", "01")
my <- ifelse(is.na(day), NA, "042020")
value <- c(34, 23)
X <- ifelse(is.na(day), NA, paste(day, my, sep = ""))
Y <- ifelse(is.na(dmy), NA, rep("30042020"))
Z <- c("01082020", "01072020")
data <- data.frame(X, Y, Z, value)
data$X <- lubridate::dmy(X)
data$Y <- lubridate::dmy(Y)
data$Z <- lubridate::dmy(Z)
data
And this is my data:
X Y Z value
1 2020-04-20 2020-04-30 2020-08-01 34
2 2020-04-01 2020-04-30 2020-07-01 23
I have three time variables. I want to create a new variable using two conditions:
Z > Y
, Y > X
and Z
and X
are not a NA
, then replace value with the letter "A
"X = 1st April
and Z > Y
, and Z
is not a NA, then replace value with the letter "B
".I am expecting a new variable called adjValue
where the first row should be A
and the second row should be B
.
This is what I wrote,
data %>% mutate(adjValue = ifelse(Z > Y & Y > X & !is.na(Z) & !is.na(X), "A", ifelse(
X == ymd(20200401) & (Z > Y) & !is.na(Z), "B", value)))
X Y Z value adjValue
1 2020-04-20 2020-04-30 2020-08-01 34 A
2 2020-04-01 2020-04-30 2020-07-01 23 A
As one can see, the adjValue
second row is showing A
instead of my expected B
. What did I do wrong here?
Upvotes: 0
Views: 59
Reputation: 1007
The problem with your code is that the second case (the one which you want to annotate as B
) is a subset of your first case (the one falling under A
). Take the second row for example, which you want to yield B
. It's true that Z > Y
, that Y > X
, and that Z
and X
are not NA
. As such, the first ifelse
will return A
. The second ifelse
is only evaluated if the condition is false.
To make your code work, you simply need to check the conditions for B
before those for A
.
data %>% mutate(adjValue = ifelse(X == ymd(20200401) & (Z > Y) & !is.na(Z), "B",
ifelse(Z > Y & Y > X & !is.na(Z) & !is.na(X), "A", value)))
Upvotes: 1
Reputation: 39595
You can try this solution:
library(lubridate)
library(tidyverse)
#Your input
day <- c("20", "01")
my <- ifelse(is.na(day), NA, "042020")
value <- c(34, 23)
X <- ifelse(is.na(day), NA, paste(day, my, sep = ""))
Y <- ifelse(is.na(dmy), NA, rep("30042020"))
Z <- c("01082020", "01072020")
data <- data.frame(X, Y, Z, value)
data$X <- lubridate::dmy(X)
data$Y <- lubridate::dmy(Y)
data$Z <- lubridate::dmy(Z)
data
#Conditions
cond1 <- (data$Z > data$Y) & (data$Y>data$X) & !is.na(data$Z) & !is.na(data$X)
cond2 <- format(data$X,'%d-%m')=='01-04' & (data$Z>data$Y) & !is.na(data$Z)
#Assign valus
data$adjvalue<-NA
data$adjvalue[cond1]<-'A'
data$adjvalue[cond2]<-'B'
X Y Z value adjvalue
1 2020-04-20 2020-04-30 2020-08-01 34 A
2 2020-04-01 2020-04-30 2020-07-01 23 B
Upvotes: 1