使用 tidy select 中的变量在 paste() 函数内。

huangapple go评论51阅读模式
英文:

Use variables from tidy select within paste()

问题

以下是翻译好的代码部分:

假设以下函数

library(tidyverse)
nest_fun <- function(data, groups) {
  data %>%
    group_by(pick({{groups}})) %>%
    nest() %>%
    mutate(filename = paste({{groups}}[1], {{groups}}[2], "file.png", sep = "_"))
}
nest_fun(data = mtcars, groups = c(vs, am))
# # A tibble: 4 × 4
# # Groups:   vs, am [4]
#      vs    am data              filename    
#   <dbl> <dbl> <list>            <chr>       
# 1     0     1 <tibble [6 × 9]>  0_1_file.png
# 2     1     1 <tibble [7 × 9]>  1_1_file.png
# 3     1     0 <tibble [7 × 9]>  1_0_file.png
# 4     0     0 <tibble [12 × 9]> 0_0_file.png

这个函数在只按照2个变量分组时运行良好。如何修改函数以便可以根据任意数量的变量分组并仍然获得正确的文件名?

英文:

Assume the following function

library(tidyverse)
nest_fun &lt;- function(data, groups) {
  data %&gt;% 
    group_by(pick({{groups}})) %&gt;% 
    nest() %&gt;% 
    mutate(filename = paste({{groups}}[1], {{groups}}[2], &quot;file.png&quot;, sep = &quot;_&quot;))
}
nest_fun(data = mtcars, groups = c(vs, am))
# # A tibble: 4 &#215; 4
# # Groups:   vs, am [4]
#      vs    am data              filename    
#   &lt;dbl&gt; &lt;dbl&gt; &lt;list&gt;            &lt;chr&gt;       
# 1     0     1 &lt;tibble [6 &#215; 9]&gt;  0_1_file.png
# 2     1     1 &lt;tibble [7 &#215; 9]&gt;  1_1_file.png
# 3     1     0 &lt;tibble [7 &#215; 9]&gt;  1_0_file.png
# 4     0     0 &lt;tibble [12 &#215; 9]&gt; 0_0_file.png

The function works fine as long as I group by exactly 2 variables. How could I write the function such that I can group by an arbitrary number of variables and still get filename correct?

答案1

得分: 1

paste(和paste0)的collapse参数将向量的元素粘贴在一起,而sep则在函数调用的参数之间粘贴。因此,您可以通过嵌套调用paste/paste0来实现想要的效果。

我强烈支持@r2evans对将数据框作为函数参数的评论。这是一个良好的实践(也允许您使用管道函数)。我看到您在问题中已经采取了这种做法。然而,将其命名为data - 这是一个内置函数的名称 - 并不理想。

英文:

The collapse argument of paste (and paste0) pastes down the elements of a vector, whereas sep pastes across the arguments of the call. Therefore you can get what you want with nested calls to paste/paste0.

I strongly support @r2evans' comment about providing the data frame as an argument to your function. It is simply good practice (and allows you to pipe your function if you wish). I see you've already actioned that in the question. However, using data - which is the name of a built-in function - as its name is not ideal.

So...

library(tidyverse)

nest_fun &lt;- function(d=mtcars, groups = c(vs, am)) {
  d %&gt;% 
    group_by(pick({{groups}})) %&gt;% 
    nest() %&gt;% 
    mutate(filename = paste0(paste({{groups}}, collapse=&quot;_&quot;), &quot;_file.png&quot;))
}

nest_fun()

# A tibble: 4 &#215; 4
# Groups:   vs, am [4]
     vs    am data              filename    
  &lt;dbl&gt; &lt;dbl&gt; &lt;list&gt;            &lt;chr&gt;       
1     0     1 &lt;tibble [6 &#215; 9]&gt;  0_1_file.png
2     1     1 &lt;tibble [7 &#215; 9]&gt;  1_1_file.png
3     1     0 &lt;tibble [7 &#215; 9]&gt;  1_0_file.png
4     0     0 &lt;tibble [12 &#215; 9]&gt; 0_0_file.png

mtcars %&gt;% nest_fun(c(vs, am, gear))

# A tibble: 7 &#215; 5
# Groups:   vs, am, gear [7]
     vs    am  gear data              filename      
  &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;list&gt;            &lt;chr&gt;         
1     0     1     4 &lt;tibble [2 &#215; 8]&gt;  0_1_4_file.png
2     1     1     4 &lt;tibble [6 &#215; 8]&gt;  1_1_4_file.png
3     1     0     3 &lt;tibble [3 &#215; 8]&gt;  1_0_3_file.png
4     0     0     3 &lt;tibble [12 &#215; 8]&gt; 0_0_3_file.png
5     1     0     4 &lt;tibble [4 &#215; 8]&gt;  1_0_4_file.png
6     0     1     5 &lt;tibble [4 &#215; 8]&gt;  0_1_5_file.png
7     1     1     5 &lt;tibble [1 &#215; 8]&gt;  1_1_5_file.png
nest_fun()

huangapple
  • 本文由 发表于 2023年4月19日 21:30:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定