代码之家  ›  专栏  ›  技术社区  ›  David T

“mutate”可在R中的tidyverse中添加两列,并使用单个fn调用

  •  0
  • David T  · 技术社区  · 5 年前

    这是一个R版本3.4.4的问题

    投票功能 voteOnBase ,接受2个参数并返回一个2元素列表: WINNER 以及 VOTE.COUNT . 我想用它将这两列添加到 notVotedYet ,一个tibble。以下代码正确运行。

     library(tidyverse)
    
     withVotes <- notVotedYet %>%
        group_by(BASE) %>%
        mutate(WINNER     = voteOnBase(BASE, CODES)[[1]],
               VOTE.COUNT = voteOnBase(BASE, CODES)[[2]])
    

    然而 voteOnBase 两次相同的输入。如何消除额外的函数调用,但仍然添加相同的两列?

    1 回复  |  直到 5 年前
        1
  •  3
  •   neilfws    5 年前

    如果没有一些示例数据和输出,回答起来并不容易,但我建议写 voteOnBase() 返回tibble,而不是列表。然后可以将结果存储在列表列中,并使用 unnest() .

    举例说明:这里有一个函数, square_it() 它与您的一样,接受2个参数并返回2个元素,但作为TIBLE中的列。

    square_it <- function(x, y) {
      tibble(x = x^2, y = y^2)
    }
    

    我们可以使用 iris 用于传递参数的数据集。我们使用 pmap() 指定变量和函数。列表列命名为 sq :

    iris %>% 
      as_tibble() %>% 
      mutate(sq = pmap(list(Sepal.Length, Sepal.Width), square_it))
    
    # A tibble: 150 x 6
       Sepal.Length Sepal.Width Petal.Length Petal.Width Species sq              
              <dbl>       <dbl>        <dbl>       <dbl> <fct>   <list>          
     1          5.1         3.5          1.4         0.2 setosa  <tibble [1 x 2]>
     2          4.9         3            1.4         0.2 setosa  <tibble [1 x 2]>
     3          4.7         3.2          1.3         0.2 setosa  <tibble [1 x 2]>
     4          4.6         3.1          1.5         0.2 setosa  <tibble [1 x 2]>
     5          5           3.6          1.4         0.2 setosa  <tibble [1 x 2]>
     6          5.4         3.9          1.7         0.4 setosa  <tibble [1 x 2]>
     7          4.6         3.4          1.4         0.3 setosa  <tibble [1 x 2]>
     8          5           3.4          1.5         0.2 setosa  <tibble [1 x 2]>
     9          4.4         2.9          1.4         0.2 setosa  <tibble [1 x 2]>
    10          4.9         3.1          1.5         0.1 setosa  <tibble [1 x 2]>
    # ... with 140 more rows
    

    只需添加 %>% unnest(sq) 到该代码,以生成列 x y :

    iris %>% 
      as_tibble() %>% 
      mutate(sq = pmap(list(Sepal.Length, Sepal.Width), square_it)) %>%
      unnest(sq)
    
    # A tibble: 150 x 7
       Sepal.Length Sepal.Width Petal.Length Petal.Width Species     x     y
              <dbl>       <dbl>        <dbl>       <dbl> <fct>   <dbl> <dbl>
     1          5.1         3.5          1.4         0.2 setosa   26.0 12.2 
     2          4.9         3            1.4         0.2 setosa   24.0  9   
     3          4.7         3.2          1.3         0.2 setosa   22.1 10.2 
     4          4.6         3.1          1.5         0.2 setosa   21.2  9.61
     5          5           3.6          1.4         0.2 setosa   25   13.0 
     6          5.4         3.9          1.7         0.4 setosa   29.2 15.2 
     7          4.6         3.4          1.4         0.3 setosa   21.2 11.6 
     8          5           3.4          1.5         0.2 setosa   25   11.6 
     9          4.4         2.9          1.4         0.2 setosa   19.4  8.41
    10          4.9         3.1          1.5         0.1 setosa   24.0  9.61
    # ... with 140 more rows
    
        2
  •  1
  •   moodymudskipper    5 年前

    您可能想使用 group_map :

    library(dplyr)
    useless_dupes <- function(x){list(x1=x, x2=x)}
    
    mtcars %>%
      group_by(cyl) %>%
      group_map(~as_tibble(useless_dupes(.$disp)))
    #> # A tibble: 32 x 3
    #> # Groups:   cyl [3]
    #>      cyl    x1    x2
    #>    <dbl> <dbl> <dbl>
    #>  1     4 108   108  
    #>  2     4 147.  147. 
    #>  3     4 141.  141. 
    #>  4     4  78.7  78.7
    #>  5     4  75.7  75.7
    #>  6     4  71.1  71.1
    #>  7     4 120.  120. 
    #>  8     4  79    79  
    #>  9     4 120.  120. 
    #> 10     4  95.1  95.1
    #> # ... with 22 more rows