簡體   English   中英

Dplyr 多管道動態變量?

[英]Dplyr multiple piped dynamic variables?

我經常這樣做:

library(tidyverse)

iris %>% 
  group_by(Species) %>% 
  summarise(num_Species = n_distinct(Species)) %>% 
  mutate(perc_Species = 100 * num_Species / sum(num_Species))

所以我想創建一個 function 輸出相同的東西,但動態命名為 num_ 和 perc_ 列:

num_perc <- function(df, group_var, summary_var) {
  
}

我發現這個資源很有用,但它沒有直接解決如何以我想要的方式重用新創建的列名。

您可以做的是在group_var上使用as_label(enquo())來提取作為字符向量傳遞的變量以生成新列。 您可以在您發送的鏈接文檔中看到一個明確的示例是6.1.3 通過這種方式,我們可以動態地將 num_ 和num_ perc_到您的匯總變量中,並且只需要傳入dfgroup_var

library(dplyr)

num_perc <- function(df, group_var) {
  summary_lbl <- as_label(enquo(group_var))
  num_lbl <- paste0("num_", summary_lbl)
  perc_lbl <- paste0("perc_", summary_lbl)
  
  df %>%
    group_by({{ group_var }}) %>%
    summarize(!!num_lbl := n_distinct({{ group_var }})) %>%
    mutate(!!perc_lbl := 100 * .data[[num_lbl]] / sum(.data[[num_lbl]]))
}

num_perc(iris, Species)
#> # A tibble: 3 × 3
#>   Species    num_Species perc_Species
#>   <fct>            <int>        <dbl>
#> 1 setosa               1         33.3
#> 2 versicolor           1         33.3
#> 3 virginica            1         33.3

group_varsummary_var實際上不同的這種情況下,它本質上是相同的解決方案。

num_perc <- function(df, group_var, summary_var) {
  summary_lbl <- as_label(enquo(summary_var))
  num_lbl <- paste0("num_", summary_lbl)
  perc_lbl <- paste0("perc_", summary_lbl)
  
  df %>%
    group_by({{ group_var }}) %>%
    summarize(!!num_lbl := n_distinct({{ summary_var }})) %>%
    mutate(!!perc_lbl := 100 * .data[[num_lbl]] / sum(.data[[num_lbl]]))
}

num_perc(iris, Species, Species)

另一種可能的解決方案,它使用deparse(substitute(...))以字符串形式獲取 function 參數的名稱:

library(tidyverse)

f <- function(df, group_var, summary_var)
{
  group_var <- deparse(substitute(group_var))
  summary_var <- deparse(substitute(summary_var))

  df %>% 
    group_by(!!sym(group_var)) %>% 
    summarise(!!str_c("num_", summary_var) := n_distinct(summary_var)) %>% 
    mutate(!!str_c("per_", summary_var) := 100 * !!sym(str_c("num_", summary_var)) / sum(!!sym(str_c("num_", summary_var))))
}

f(iris, Species, Species)

#> # A tibble: 3 × 3
#>   Species    num_Species per_Species
#>   <fct>            <int>       <dbl>
#> 1 setosa               1        33.3
#> 2 versicolor           1        33.3
#> 3 virginica            1        33.3

您確定 n_distinct 是您想要做的嗎? 在 iris 數據集的情況下,有三個 Species - setosa, versicolor, virginica。 因此,每個物種都是1/3的獨特物種。 Iris 數據集是平衡的,因為每個物種有 50 個,因此每個物種代表數據集的 1/3,但更一般地說,情況並非如此。

帶有數據屏蔽的 function 將為您覆蓋不平衡的數據集:

library(dplyr)
my_func <- function(df, var, percent){
  df %>%
    count({{var}}) %>%
    mutate(percent = 100 * n/sum(n))
}

my_func(iris, Species, percent)

iris %>%
  my_func(Species, percent) #or with pipe

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM