R通过列嵌套地图 [英] R nested map through columns

查看:76
本文介绍了R通过列嵌套地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在这里解决的功能.
此函数采用填充有注释的列和另一个分组列,并将注释传播到缺少值的行.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆