r - 整洁的评估:如何在依赖 %>% 管道的自定义函数中使用 dplyr::na_if 作为可选参数
问题描述
我正在尝试编写一个函数,该函数需要一个数据框,将一列从 转换chr
为dbl
,然后将 1 添加到一列。我还想选择性地将某些值替换为NA
. 否则,如果不使用相关参数,我希望函数跳过 NA 替换步骤。
数据
library(tibble)
library(dplyr)
library(magrittr)
df <-
tibble(id = 1:10, col_of_interest = 21:30) %>%
add_row(id = 11, col_of_interest = 999) %>%
mutate(across(col_of_interest, as.character))
df
## # A tibble: 11 x 2
## id col_of_interest
## <dbl> <chr>
## 1 1 21
## 2 2 22
## 3 3 23
## 4 4 24
## 5 5 25
## 6 6 26
## 7 7 27
## 8 8 28
## 9 9 29
## 10 10 30
## 11 11 999
编写函数
该功能应:
- 接受数据。
col_of_interest
从转换chr
为dbl
。- 替换
999
为 NA (但前提是我指定999
应该替换为NA
) - 添加
1
到col_of_interest
我的尝试
在编写我的函数时,我受到两个资源的指导:
add_one <- function(data, var, na_if_val = NULL) {
data %>%
mutate(across({{ var }}, as.numeric)) %>%
{if( is.null( {{ na_if_val }} )
) . # <--- the dot means: "return the preexisting dataframe"
else
na_if( {{ na_if_val }} )
} %>%
mutate(across({{ var }}, add, 1))
}
当我在我的df
对象上测试函数时,我得到一个错误。
add_one(data = df,
var = col_of_interest,
na_if_val = "999")
Error in check_length(y, x, fmt_args("y"), glue("same as
{fmt_args(~x)}")) : argument "y" is missing, with no default
谷歌搜索这个错误产生了这个页面,说明:
但是请注意,na_if() 只能接受长度为 1 的参数。
但是,仅合并na_if( {{ na_if_val }} )
到add_one
函数的管道中确实有效。这是条件评估与is.null
导致功能中断的结合。我不明白为什么。
解决方案
你有几个问题,但主要是因为你做错了非标准评估。
add_one <- function(data, var, na_if_val = NULL) {
var_b <- enquo(var)
data <- data %>%
mutate(across(!!var_b, as.numeric))
if(!is.null(na_if_val)){
data <- data %>%
mutate(across(!!var_b, na_if, y = na_if_val))
}
data <- data %>%
mutate(across(!!var_b, add, 1))
return(data)
}
返回这个:
add_one(df, col_of_interest, 999)
# A tibble: 11 x 2
id col_of_interest
<dbl> <dbl>
1 1 22
2 2 23
3 3 24
4 4 25
5 5 26
6 6 27
7 7 28
8 8 29
9 9 30
10 10 31
11 11 NA
首先,您需要在函数中引用感兴趣的变量enquo()
,然后,在您想要的位置取消引用该变量(使用 bang bang !!
)。您的函数的另一个问题是在管道中间插入您的 if 语句,这不起作用。如果需要在特殊情况下应用某些方法,则需要与主计算分开评估。
推荐阅读
- python - 计算两列之间的不同集,同时使用 agg 函数 Pyspark Spark Session
- python - 使用不受支持的过滤器修复 PDF 文件
- android - Android 构建失败 - 无法找到 Guava 存储库
- java - 我的打印语句循环一次后循环两次
- javascript - React Hooks - 没有上下文的全局状态
- node.js - 如何使用 google docs api 将文本文件转换为 google doc
- amazon-web-services - 为什么我的 aws 批处理作业不能全部启动并并行运行?
- mongodb - 在数组中查找并创建或更新对象
- php - 根据此脚本中的最后修改日期对 apache 目录进行排序
- python - 有没有办法在 python 中不使用 str 将数字、括号等转换为字符串类型?