使用自定义参数创建列函数

creating a column function with custom parameters

我在这里有一个问题:

创建一个包含 10 列的虚拟数据框“df_test” (1)“INT1”的样本值介于 1 和 10

之间

(1)“df”- 数据帧

(2)“col_test”- 要测试指定列中的每一行值是偶数还是奇数的列的名称。

(3) ' col_multiply' - 存储 'col_test' 结果的列的名称 如果 'col_test' 为偶数则乘以 2,如果 [=] 则乘以 3 47=] 是奇数

(4) 函数结束返回整个 df 和结果

这是我的代码:

df_test = data.frame(INT1 = (sample(x = c(1:10),size = 10, replace = F)))
df_test

check_even = function(df, col_test, col_multiply) {
    df$res = ifelse(df[col_test,] %% 2 == 0, df[,col_multiply] * 2, df[,col_multiply] * 3)
    return(df)} #wrong

#run code
check_even(df_test, 'INT1','res')

在上面的代码中,我得到:

我还尝试了另一种使用 dplyr 的方法:

df_test = data.frame(INT1 = (sample(x = c(1:10),size = 10, replace = F)))
df_test

library(dplyr)

    check_even = function(df, col_test, col_multiply){
      df %>%
        mutate(res = ifelse({{col_test}} %% 2 == 0, {{col_multiply}} * 2, {{col_multiply}} * 3))
    }  
    
    check_even(df_test, 'INT1', 'res')

但是,我仍然收到错误消息:

Error in mutate(., res = ifelse({ : Caused by error in "INT1" %% 2: ! non-numeric argument to binary operator

我该如何解决这个问题?提前谢谢你。

基础 R

这是更正的基本 R 函数。

df_test = data.frame(INT1 = (sample(x = c(1:10),size = 10, replace = FALSE)))
#df_test

check_even = function(df, col_test, col_multiply) {
  df[[col_multiply]] = ifelse(df[[col_test]] %% 2 == 0, df[[col_test]] * 2, df[[col_test]] * 3)
  return(df)
}

#run code
check_even(df_test, 'INT1','res')
#>    INT1 res
#> 1     4   8
#> 2     5  15
#> 3     1   3
#> 4     8  16
#> 5     2   4
#> 6     9  27
#> 7     3   9
#> 8     7  21
#> 9    10  20
#> 10    6  12

reprex package (v2.0.1)

于 2022-06-04 创建

dplyr解法

library(dplyr)

check_even = function(df, col_test, col_multiply){
  df %>%
    mutate({{col_multiply}} := ifelse({{col_test}} %% 2 == 0, {{col_test}} * 2, {{col_test}} * 3))
}  

check_even(df_test, INT1, res)

我认为你需要这个,如果我没看错你应该改变你的逻辑:

您可以在函数体中计算它,而不是将结果列作为参数传递:

library(dplyr)

check_even = function(df, col_test){
  
  df %>%
    mutate(res = ifelse({{col_test}} %% 2 == 0, {{col_test}} * 2, {{col_test}} * 3))
}  

check_even(df_test, INT1)

   INT1 res
1    10  20
2     3   9
3     6  12
4     4   8
5     7  21
6     9  27
7     5  15
8     2   4
9     1   3
10    8  16