Reputation: 785
I wrote a function to expand annotations within groups.
function(data, group_col, expand_col){
data %>%
dplyr::group_by(!!rlang::ensym(group_col)) %>%
dplyr::mutate(
!!rlang::ensym(expand_col) = dplyr::case_when(
!is.na(!!rlang::ensym(expand_col)) ~
!!rlang::ensym(expand_col) ,
any( !is.na(!!rlang::ensym(expand_col)) ) & is.na(!!rlang::ensym(expand_col)) ~
paste(unique(unlist(str_split(na.omit(!!rlang::ensym(expand_col)), " ")) ), collapse = " "),
TRUE ~
NA_character_
)
) %>%
dplyr::ungroup()
}
This should take a tibble like this:
> t <- structure(list(a = c("a", "b", "c", "d", "e", "f", "g", "h"),
b = c(1, 1, 1, 1, 2, 2, 2, 2), c = c(NA, NA, NA, "D", "E",
NA, NA, NA)), row.names = c(NA, -8L), class = c("tbl_df",
"tbl", "data.frame"))
> t
# A tibble: 8 x 3
a b c
<chr> <dbl> <chr>
1 a 1 NA
2 b 1 NA
3 c 1 NA
4 d 1 D
5 e 2 E
6 f 2 NA
7 g 2 NA
8 h 2 NA
And make it became it:
> t %>%
+ dplyr::group_by(b) %>%
+ dplyr::mutate(
+ c = dplyr::case_when(
+ !is.na(c) ~ c ,
+ any( !is.na(c) ) & is.na(c) ~
+ paste(unique(unlist(str_split(na.omit(c), " ")) ), collapse = " "),
+ TRUE ~
+ NA_character_
+ )
+ ) %>%
+ dplyr::ungroup()
# A tibble: 8 x 3
a b c
<chr> <dbl> <chr>
1 a 1 D
2 b 1 D
3 c 1 D
4 d 1 D
5 e 2 E
6 f 2 E
7 g 2 E
8 h 2 E
Anyone knows whats is the problem with this approach or have any better strategy to assing element in a group by expanding some previously assigned element.
Upvotes: 2
Views: 127
Reputation: 887088
An option would be to use curly-curly
({{...}}
) for doing this in a more compact way
f1 <- function(data, group_col, expand_col){
data %>%
dplyr::group_by({{group_col}}) %>%
dplyr::mutate(
{{expand_col}} := dplyr::case_when(
!is.na({{expand_col}}) ~
{{expand_col}} ,
any( !is.na({{expand_col}}) ) & is.na({{expand_col}}) ~
paste(unique(unlist(str_split(na.omit({{expand_col}}), " ")) ),
collapse = " "),
TRUE ~
NA_character_
)) %>%
dplyr::ungroup()
}
f1(t, b, c)
# A tibble: 8 x 3
# a b c
# <chr> <dbl> <chr>
#1 a 1 D
#2 b 1 D
#3 c 1 D
#4 d 1 D
#5 e 2 E
#6 f 2 E
#7 g 2 E
#8 h 2 E
Upvotes: 1