如何修复我的自定义函数以处理包含非数字变量的数据帧

How do I fix my custom function to work on dataframes that include non-numeric variable

我创建了以下将数字列转换为比例的函数 -

library(tidyverse)

my_function_2 <- function(data, var, round = 4){
    
    var_expr <- rlang::enquo(var)
    colnm_expr <- paste(rlang::get_expr(var_expr), "pct", sep = "_")
    
    data %>%
        mutate(!! colnm_expr := !!var_expr/sum(!!var_expr)) %>%
        round(round)
    
}

然而,它似乎只有在数据框“只有”数值时才有效。例如,它适用于这样的东西 -

mtcars %>% 
    count(cyl) %>% 
    my_function_2(var = n)

 cyl  n  n_pct
1   4 11 0.3438
2   6  7 0.2188
3   8 14 0.4375

但是,如果使用具有非数字列的数据框,我会收到错误消息,即使我尝试在数字列上使用该函数 -

# Sample dataframe
groups <- c("group 1", "group 2", "group 3", "group 4", "group 5")
data   <- c(50000, 60000, 70000, 100000, 80000)
df <- tibble(groups, data)

# Test function on `data` column
df %>% my_function_2(var = data)

当我尝试上面的代码时,出现以下错误 -

 Error in Math.data.frame(list(groups = c("group 1", "group 2", "group 3",  : 
  non-numeric variable(s) in data frame: groups 

似乎错误告诉我数据框中有非数字变量。但是我不确定为什么这是一个问题,因为我试图在作为数字列的“数据”变量上使用该函数。我该如何修复此功能?

问题是 roundmutate 之外。因此,在 mtcars 数据中,这并不重要,因为列都是 numeric,而在创建的数据集中,'groups' 是 character

round(df$groups)
Error in round(df$groups) : non-numeric argument to mathematical function

我们可以将函数更改为 round 仅感兴趣的列,即在 mutate 本身

my_function_2 <- function(data, var, round = 4){
    
    var_expr <- rlang::enquo(var)
    colnm_expr <- paste(rlang::get_expr(var_expr), "pct", sep = "_")
    
    data %>%
        mutate(!! colnm_expr := !!var_expr/sum(!!var_expr) %>%
                            round(round))
    
    
    }

-测试

df %>%
    my_function_2(var = data)
# A tibble: 5 x 3
  groups    data data_pct
  <chr>    <dbl>    <dbl>
1 group 1  50000    0.139
2 group 2  60000    0.167
3 group 3  70000    0.194
4 group 4 100000    0.278
5 group 5  80000    0.222