[英]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_
到您的匯總變量中,並且只需要傳入df
和group_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_var
和summary_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.