0

I've got a table, . During data collection, some of these blades were measured exactly (variable <Max_Length>), and some were put in general size categories (variable <Size_Grade>). What I want to do now is assign size categories to the blades that have exact measurements. For example, if a blade was measured at 31.7 millimeters, it currently has an NA in <Size_Grade>, which I'd like to replace with the value 4, meaning that it fell between 3 and 4 centimeters in length (both <Max_Length> and <Size_Grade> have the type Double). If <Size_Grade> isn't NA, I just want it to leave it alone.

I'm trying to do that with the following if...elseif statements in a for loop.

for(Size_Grade in blades) {
if (is.NA(blades$Size_Grade) == TRUE){
      blades$Size_Grade = blades$Size_Grade
} elseif (blades$Max_Length <= 5){
      blades$Size_Grade = 0.5
} elseif (blades$Max_Length > 5 & blades$Max_Length <= 10){
      blades$Size_Grade = 1
} elseif (blades$Max_Length > 10 & blades$Max_Length <= 20){
      blades$Size_Grade = 2
} elseif (blades$Max_Length > 20 & blades$Max_Length <= 30){
      blades$Size_Grade = 3
} elseif (blades$Max_Length > 30 & blades$Max_Length <= 40){
      blades$Size_Grade = 4
} elseif (blades$Max_Length > 40 & blades$Max_Length <= 50){
      blades$Size_Grade = 5
} elseif (blades$Max_Length > 50 & blades$Max_Length <= 60){
      blades$Size_Grade = 6
} elseif (blades$Max_Length > 60 & blades$Max_Length <= 70){
      blades$Size_Grade = 7
} elseif (blades$Max_Length > 70 & blades$Max_Length <= 80){
      blades$Size_Grade = 8
} elseif (blades$Max_Length > 80 & blades$Max_Length <= 90){
      blades$Size_Grade = 9
} elseif (blades$Max_Length > 110 & blades$Max_Length <= 120){
      blades$Size_Grade = 12
} elseif (blades$Max_Length > 140 & blades$Max_Length <= 150){
      blades$Size_Grade = 150
} elseif (is.NA(blades$Max_Length == TRUE)){
      blades$Size_Grade = NA
}
}

I get the following error message

Error: unexpected symbol in:
"      blades$Size_Grade = blades$Size_Grade
} elseif"

I'm guessing that I'm just formatting something wrong in the if...elseif statement, but I can't figure out what. (If this is a dumb way to try to achieve what I'm going for, I'm also open to alternatives.) Thanks!

  • 1
    `elseif` isn't a statement in R, try `else if` instead (note the space between) – nrennie Feb 23 '23 at 23:15
  • Help others help you. Provide code for a minimal reproducible example and some data. We have no idea what `blades$Size_Grade` looks like = is it a dataframe, a list? – nrennie Feb 23 '23 at 23:21
  • 1
    try `case_when` in `dplyr` package. less verbose and cleaner code – Eric Feb 23 '23 at 23:27
  • 1
    `ifelse` is the base R method (no case-when functionality), the recommendation for `else if` is missing the fact that you're doing this on a whole vector at a time, `if` is wrong here. Also, your use of ranges `<= 5` (etc) suggests the use of `findInterval` or `cut`, can reduce all of this to one or two lines of code. – r2evans Feb 23 '23 at 23:44
  • I switched to case_when, and it's handling what I need much more nicely! Thank you. – Lauren Pratt Feb 24 '23 at 00:06
  • I'd suggest taking a look at the [FAQ on binning data](https://stackoverflow.com/q/5570293/903061). It's hard to tell exactly without sample data, but I think your entire code code be simplified to something like `blades$Size_Grade = with(blades, ifelse(is.na(Size_Grade), cut(Max_length, breaks = c(0, 5, seq(10, 90, by = 10), 120, Inf), labels = c(0.5, 1:9, 12, 150, )), Size_Grade))`. Though you've got a gap where blades sized 121-140 are not classified... – Gregor Thomas Feb 24 '23 at 01:48

0 Answers0