Steen Harsted
Steen Harsted

Reputation: 1932

using positional occurence of value in the LHS of case_when()

Can I use the positional occurrence of a value in the left-hand-side (LHS) of dplyr::case_when()?

In the example data, I would like to create y so that it only contains the last occurrence of "A" in x and the first occurrence of "B" in x.

Library and data:

library(dplyr)

# Data
df <- tibble(
  x = c(NA, "A", "A", NA, NA, "B", "B"))
df
#> # A tibble: 7 x 1
#>   x    
#>   <chr>
#> 1 <NA> 
#> 2 A    
#> 3 A    
#> 4 <NA> 
#> 5 <NA> 
#> 6 B    
#> 7 B

Desired result

tibble(
  x = c(NA, "A", "A", NA, NA, "B", "B"),
  y = c(NA, NA, "A", NA, NA, "B", NA))
#> # A tibble: 7 x 2
#>   x     y    
#>   <chr> <chr>
#> 1 <NA>  <NA> 
#> 2 A     <NA> 
#> 3 A     A    
#> 4 <NA>  <NA> 
#> 5 <NA>  <NA> 
#> 6 B     B    
#> 7 B     <NA>

One of my failed attempts

df %>% 
  mutate(
    y = case_when(
      x == last(x == "A")  ~ "A",
      x == first(x == "B") ~ "B")
  )
#> # A tibble: 7 x 2
#>   x     y    
#>   <chr> <chr>
#> 1 <NA>  <NA> 
#> 2 A     <NA> 
#> 3 A     <NA> 
#> 4 <NA>  <NA> 
#> 5 <NA>  <NA> 
#> 6 B     <NA> 
#> 7 B     <NA>

Created on 2019-11-28 by the reprex package (v0.3.0)

Upvotes: 1

Views: 151

Answers (1)

akrun
akrun

Reputation: 887471

We need the position

library(dplyr)
df %>%
    mutate(y = replace(x, first(which(x  %in% "A")), NA),
           y = replace(y, last(which(x %in% "B")), NA))
# A tibble: 7 x 2
#  x     y    
#  <chr> <chr>
#1 <NA>  <NA> 
#2 A     <NA> 
#3 A     A    
#4 <NA>  <NA> 
#5 <NA>  <NA> 
#6 B     B    
#7 B     <NA> 

Or use match to get the index

df %>% 
   mutate(y = replace(x, c(match("A",  x), n() +1 - match("B", rev(x))), NA))

Or using case_when

df %>% 
  mutate(y = case_when((duplicated(x == "A", fromLast = TRUE) & 
           x %in% "A") |(duplicated(x == "B") & x %in% "B") ~ NA_character_,
          TRUE ~ x))

Upvotes: 1

Related Questions