Issue with NA in conditionals in for-loop

Viewed 41

I have the following dataset:

date <- as.Date(c('2010-11-1','2010-11-2','2010-11-3','2010-11-4','2010-11-5','2010-11-6','2010-11-7','2010-11-8','2010-11-9','2010-11-10'))
precipitation <- c(0, 11, NA,3,0,0,13,7,9,10)
snowheight <- c(5,7,56,32, 11, 24, NA,8, 13, 11)
temperature <- c(-5, -2, 0, 0.4, NA, 5,6,4, 9, 10)

df <- data.frame(date, precipitation, snowheight, temperature)

I am trying to create a dichotomous variable with (0 and 1) for each datasample based on the following conditions:

  • if snowheight > 10 we continue with the conditions below. Else assign NA to the dichotomous variable.
  • if precipitation =< 0 we assign 0
  • if precipitation > 0 and temperature > 0 we assign 1.
  • if precipitation > 0 and temperature < 0 we assign 0.
  • if one of the conditional variable contains NA, NA should be assigned to the dichtomous variable as well.

Here is the desired output:

date precipitation snowheight temperature dicht
1  2010-11-01             0          5        -5.0    NA
2  2010-11-02            11          7        -2.0    NA
3  2010-11-03            NA         56         0.0    NA
4  2010-11-04             3         32         0.4     1
5  2010-11-05             0         11          NA    NA
6  2010-11-06             0         24         5.0     0
7  2010-11-07            13         NA         6.0    NA
8  2010-11-08             7          8         4.0    NA
9  2010-11-09             9         13         9.0     1
10 2010-11-10            10         11        10.0     1

I have the following loop that works fine if there is no NA in the data:

for (i in seq_len(nrow(df))){
  if (df$snowheight[i] > 10){
    if (df$precipitation[i] > 0){
      if (df$temperature[i]> 0){
        df$dicht[i] <- 1
      } else {
        df$dicht[i] <- 0
      }
    } else {
      df$dicht[i] <- 0
    }
  } else {
    df$dicht[i] <- NA
  }
}

However, since my data contains NA, I get the following error:

Error in if (df$precipitation[i] > 0) { : 
  missing value where TRUE/FALSE needed

I tried this solution but I get the same error:

for(i in seq_len(nrow(df))){
  if (is.na(df$snowheight[i])){
    df$dicht[i] <- NA
  } else if (df$snowheight[i] > 10){
    if(df$precipitation[i] > 0){
      if(df$temperature[i]> 0){
        df$dicht[i] <- 1
      } else {
        df$dicht[i] <- 0
      }
    } else {
      df$dicht[i] <- 0
    }
  } else {
    df$dicht[i] <- NA
  }
  if (is.na(df$precipitation[i])){
    df$dicht[i] <- NA
  }
  if (is.na(df$temperature[i])){
    df$dicht[i] <- NA
  }
}

Hope you can help. Let me know if you need more info. Thanks in advance.

1 Answers

if/else is not vectorized. We can use case_when with first condition that checks for 'snowheight' value less than or equal to 10 and assign it to NA, then we do the other checks (where implicitly it would be 'snowheight' greater than 10)

library(dplyr)
df %>% 
   mutate(dicht = case_when(is.na(snowheight)|is.na(precipitation)|
            is.na(temperature)|snowheight <=10 ~ NA_real_, 
            precipitation <= 0 ~ 0, 
            precipitation > 0 & temperature  > 0 ~ 1, 
            precipitation > 0 & temperature  < 0 ~ 0))
Related