R通过列嵌套地图 [英] R nested map through columns
问题描述
我有一个在这里解决的功能.
此函数采用填充有注释的列和另一个分组列,并将注释传播到缺少值的行.
I got a function which was solved here.
This function takes a column filled with annotations and another grouping column and propagates the annotation to rows with missing values.
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()
}
现在,我想通过将列分组( group_col
)和注释列( expand_col
)的许多列来做到这一点.
所以如果我有这个df:
Now I would like to do it through many columns grouping columns (group_col
) and annotations columns (expand_col
).
So if I have this df:
t <- tibble(a = c("a", "b", "c", "d", "e", "f", "g", "h"),
b = c( 1, 1, 1, 1, 2, 2, 2, 2),
c = c( 1, 1, 2, 2, 3, 3, 4, 4),
d = c( NA, NA, NA, "D", "E", NA, NA, NA),
e = c("A", NA, "C", NA, NA, NA, "G", "H")
)
我可以这样应用
> t %>%
+ f1(c,e) %>%
+ f1(b,e) %>%
+ f1(c,d) %>%
+ f1(b,d)
# A tibble: 8 x 5
a b c d e
<chr> <dbl> <dbl> <chr> <chr>
1 a 1 1 D A
2 b 1 1 D A
3 c 1 2 D C
4 d 1 2 D C
5 e 2 3 E G H
6 f 2 3 E G H
7 g 2 4 E G
8 h 2 4 E H
因此,我有3组列,即id,分组列(2:3)和注释列(4:5).
由于我多次调用该函数,所以我想知道如何使用map函数来传递列索引以应用该函数,就像上面的示例一样.
So, I have 3 groups of columns, the ids, the grouping columns (2:3), and annotation columns (4:5).
Since I call the function many times, I'd like to know how to use the map function to pass the column indexes to apply the function like in the example above.
我尝试过类似的事情
3:2 %>%
map(
function(x) 4:5 %>%
map(
function(y) f1(
t,
!!(colnames(t)[x]) ,
!!(colnames(t)[y])
)
)
)
但是结果是一团糟.
预先感谢
推荐答案
由于 f1
接受列名,因此需要首先将索引转换为符号:
Since f1
accepts column names, you need to first convert your indices to symbols:
v1 <- rlang::syms( colnames(t)[3:2] )
v2 <- rlang::syms( colnames(t)[4:5] )
现在,您可以使用 tidyr :: crossing()
获取所有可能的符号对,并使用 purrr :: reduce2()
依次应用带有这些符号的f1()
:
Now, you can use tidyr::crossing()
to get all possible pairs of your symbols, and purrr::reduce2()
to sequentially apply f1()
with those symbols:
V <- tidyr::crossing( v1, v2 )
Res <- purrr::reduce2( V$v1, V$v2, f1, .init=t )
# Validation
Res2 <- t %>% f1(c,e) %>% f1(b,e) %>% f1(c,d) %>% f1(b,d)
identical(Res, Res2) # TRUE
这篇关于R通过列嵌套地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!