对注解扩展函数的惰性求值
Lazy evaluation to annotations expanding function
我写了一个函数来扩展组内的注释。
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()
}
这应该是这样的:
> 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
并让它成为:
> 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
任何人都知道这种方法有什么问题,或者有任何更好的策略通过扩展一些先前分配的元素来分配组中的元素。
一种选择是使用 curly-curly
({{...}}
) 以更紧凑的方式执行此操作
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
我写了一个函数来扩展组内的注释。
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()
}
这应该是这样的:
> 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
并让它成为:
> 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
任何人都知道这种方法有什么问题,或者有任何更好的策略通过扩展一些先前分配的元素来分配组中的元素。
一种选择是使用 curly-curly
({{...}}
) 以更紧凑的方式执行此操作
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