Reputation: 1932
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(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
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>
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
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