我想使用分位数函数(quantile
)创建一个函数,该函数可以在dplyr
环境中通过切点生成分位数值。
例如,我想创建一个函数,使结果如下。
# load library and data
library(dplyr); library(rlang)
iris <- iris
cut_points_1 <- c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1)
quantile(iris$Sepal.Length, cut_points_1)
0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 95% 100%
4.300 4.800 5.000 5.270 5.600 5.800 6.100 6.300 6.520 6.900 7.255 7.900
但是,我无法理解如何在我的函数中管理这个部分(iris$Sepal.Length
)。具体来说,当使用非dplyr函数(例如quantile
)时,我不知道如何在data.frame中调用变量名。换句话说,当data
和var_name
的名称在我的函数中发生变化时,我不知道如何在函数中编写data$var_name
。
以下是我的代码和功能。
# load library and data
library(dplyr); library(rlang)
iris <- iris
# cut-points (percentage)
cut_points_1 <- c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1)
cut_points_2 <- c(0, 0.2, 0.4, 0.6, 0.8, 1)
# function
cut <- function(data, var_name, cut_points) {
data <- enquo(data)
cut_points <- enquo(cut_points)
varname_cut <- paste0(substitute(var_name), "_cut") # different variable name: source(https://stackoverflow.com/questions/46131829/unquote-the-variable-name-on-the-right-side-of-mutate-function-in-dplyr/46132317?noredirect=1#comment79234301_46132317)
!!varname_cut := quantile(!!data$!!var_name, cut_points) # <- This is the problem!
}
# run
cut(iris, Sepal.Length, cut_points_1)
cut(iris, Sepal.Length, cut_points_2)
答案 0 :(得分:2)
这是一个解决方案,使您的功能适应它:
# load library and data
library(dplyr, warn.conflicts = F)
iris <- iris
# cut-points (percentage)
cut_points_1 <- c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1)
cut_points_2 <- c(0, 0.2, 0.4, 0.6, 0.8, 1)
# function
cut <- function(data, var_name, cut_points) {
var_name <- enquo(var_name)
varname_cut <- paste0(quo_name(var_name), "_cut")
tibble(cut_points = cut_points,
!!varname_cut := data %>% pull(!!var_name) %>% quantile(cut_points))
}
# run
cut(iris, Sepal.Length, cut_points_1)
#> # A tibble: 12 x 2
#> cut_points Sepal.Length_cut
#> <dbl> <dbl>
#> 1 0.00 4.300
#> 2 0.10 4.800
#> 3 0.20 5.000
#> 4 0.30 5.270
#> 5 0.40 5.600
#> 6 0.50 5.800
#> 7 0.60 6.100
#> 8 0.70 6.300
#> 9 0.80 6.520
#> 10 0.90 6.900
#> 11 0.95 7.255
#> 12 1.00 7.900
cut(iris, Sepal.Length, cut_points_2)
#> # A tibble: 6 x 2
#> cut_points Sepal.Length_cut
#> <dbl> <dbl>
#> 1 0.0 4.30
#> 2 0.2 5.00
#> 3 0.4 5.60
#> 4 0.6 6.10
#> 5 0.8 6.52
#> 6 1.0 7.90
我添加了一个带有cut_points的列,以获得类似quantile
结果的内容。如果需要,您可以使用%
格式化
enquo
和data
上使用cut_points
,因为您不需要在功能中使用它们。它们作为对象传递。quo_name
获取您的quosure的名称以将其粘贴dplyr::pull
将数据列作为向量,而不是单列 tibble