rangeelo
rangeelo

Reputation: 118

dplyr case when: only 1st instance is affected

I have a data frame, where I want to change some values in one of the columns.

The column values look like this:

[1] "soft corals" "soft corals" "soft corals" "soft corals" "soft corals" "soft corals" "soft corals" [8] "soft corals" "soft corals" "..5" "..5" "..5" "..5" "..5"
[15] "..5" "..5" "..5" "..5" "..6" "..6" "..6"
[22] "..6" "..6" "..6" "..6" "..6" "..6" "..7"
[29] "..7" "..7" "..7" "..7" "..7" "..7" "..7"
[36] "..7" "..8" "..8" "..8" "..8" "..8" "..8"
[43] "..8" "..8" "..8" "..9" "..9" "..9" "..9"
[50] "..9" "..9" "..9" "..9" "..9" "..10" "..10"
[57] "..10" "..10" "..10" "..10" "..10" "..10" "..10"
[64] "..11" "..11" "..11" "..11" "..11" "..11" "..11"
[71] "..11" "..11" "sea fans" "sea fans" "sea fans" "sea fans" "sea fans"
[78] "sea fans" "sea fans" "sea fans" "sea fans" "..13" "..13" "..13"
[85] "..13" "..13" "..13" "..13" "..13" "..13" "..14"
[92] "..14" "..14" "..14" "..14" "..14" "..14" "..14"
[99] "..14"

I want to replace the numbers with the preceding value, say "soft corals" or "sea fans" depending on the position

My code looks like this (ah is the data frame obj, cor_type is the column name):

ah <- ah %>% mutate(cor_n = case_when(stringi::stri_detect(str = cor_type, regex = "\\.") ~lag(cor_type),
                                     TRUE ~ cor_type
            )
          )

This however only changes the first instance of the regex match, i.e, at the 9th row. The rest of the values remain the same. I guess I'm wrong in my assumption about how mutate works? PS: I don't want to write a for-loop

Upvotes: 1

Views: 338

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 389155

I don't think case_when is the best choice here. One way would be to replace values with pattern (\\.) to NA and then fill NAs with previous non-NA value.

library(tidyverse)

ah %>%
  mutate(cor_type = replace(cor_type, str_detect(cor_type, "\\."), NA)) %>%
  fill(cor_type)

#    a    cor_type
#1   1 soft corals
#2   2 soft corals
#3   3 soft corals
#4   4 soft corals
#5   5 soft corals
#6   6 soft corals
#7   7    sea fans
#8   8    sea fans
#9   9    sea fans
#10 10    sea fans

data

Created a small reproducible example to work on.

ah <- data.frame(a = 1:10, cor_type = c("soft corals", "soft corals",
      "..5", "..5", "..5","..6", "sea fans", "sea fans", "..13", "..14" ))

ah
#    a    cor_type
#1   1 soft corals
#2   2 soft corals
#3   3         ..5
#4   4         ..5
#5   5         ..5
#6   6         ..6
#7   7    sea fans
#8   8    sea fans
#9   9        ..13
#10 10        ..14

Upvotes: 3

Related Questions