'designating a factor level in r depending on multiple conditions

I need to designate three different directions of a moving cell: backward, forward and stop depending on multiple conditions. The important columns for this data frame are angledeg.fac (same as angledeg but NAs are designated as stops) and angchange.

The multiple conditions are:

  1. The first non-stop position of each compID is forward.
  2. When angledeg.fac is stop, then direction is stop
  3. When angchange>145 & <210, the direction reverses (e.g., backward to forward and vv)
  4. Once #3 happens, the cell stays in that direction until #3 is fulfilled again.
  5. when there is a stop, the next non-stop position should be the last non-stop position. For example: forward, backward, stop, stop. Here, the next position is backward.

I wrote a function that can do 1-2 but I am not successful with the rest. I am doing this function in a big dataframe with tons of compIDs, so it makes sense to just pass the function in dplyr.

Here's the function:

    dirfunc <- function (angchange, angledeg.fac) {
  dirn <- ifelse (angledeg.fac=="stop", "stop", "forward")
  dirn <- ifelse (dirn=="forward" &  angchange>145 & angchange<210, "backward", "forward")
  dirn <- ifelse (angledeg.fac=="stop", "stop", dirn)
  return(dirn)
}

And here's where I apply my code:

df <- df2 %>%
  group_by(compID) %>%
  arrange(compID, T) %>% 
  mutate(angledeg = anglefun(X, lag(X), Y, lag(Y))) %>%
  mutate (angleprev = repeat.before(angledeg)) %>% # used to fill angledeg NA values with the last non-NA value
  mutate (angledeg.fac = replace_na (angledeg, "stop")) %>% # replaces NA with stop, column is char
  mutate (angchange = round (diff.func(angleprev, lag(angleprev)))) %>% # get the difference between angles
  mutate (direction.func = dirfunc (angchange, angledeg.fac)) %>% 
  mutate(dircor = ifelse(is.na(direction.func), "forward", direction.func)) #first non-stop position as fow=rward

And here's a sample data frame:

    structure(list(ID = c(1691L, 1691L, 1691L, 1691L, 1691L, 1691L
), quality = c(1.99704551697, 3.06406211853, 3.35961794853, 3.10615110397, 
2.95867657661, 3.91532421112), X = c(535.723945697, 535.142269317, 
534.560592938, 536.305622077, 536.305622077, 534.560592938), 
    Y = c(269.316163798, 268.734487418, 269.316163798, 268.734487418, 
    269.316163798, 269.897840177), T = c(414, 415, 416, 417, 
    418, 419), day = c("Day7", "Day7", "Day7", "Day7", "Day7", 
    "Day7"), rep = c("Series012", "Series012", "Series012", "Series012", 
    "Series012", "Series012"), aggregatecond = c("Aggregate", 
    "Aggregate", "Aggregate", "Aggregate", "Aggregate", "Aggregate"
    ), compID = c("Day7-Aggregate-Series012-1691", "Day7-Aggregate-Series012-1691", 
    "Day7-Aggregate-Series012-1691", "Day7-Aggregate-Series012-1691", 
    "Day7-Aggregate-Series012-1691", "Day7-Aggregate-Series012-1691"
    ), angledeg = c(NA, 225, 134.99999995075, 270, 90, 161.565051196778
    ), angleprev = c(NA, 225, 134.99999995075, 270, 90, 161.565051196778
    ), angledeg.fac = c("stop", "225", "134.99999995075", "270", 
    "90", "161.565051196778"), angchange = c(NA, NA, 90, 135, 
    180, 72), direction.func = c("stop", NA, "forward", "forward", 
    "backward", "forward"), dircor = c("stop", "forward", "forward", 
    "forward", "backward", "forward")), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(
    compID = "Day7-Aggregate-Series012-1691", .rows = structure(list(
        1:6), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -1L), .drop = TRUE))

I would appreciate any help or hints. I have been trying to figure this out for two days. Thank you!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source