自定义R语言paste函数:处理...参数获取所有值的问题
自定义paste函数MYpaste的问题修复
你想要实现一个过滤空字符串的paste()变体MYpaste,但当前版本在传入多个对象时无法正确处理...参数,仅识别第一个对象,导致结果不符合预期。
当前实现代码
MYpaste <- function(..., sep = "", collapse = NULL, recycle0 = FALSE) { x <- as.list(...) x <- x[x != ""] paste(x, sep = sep, collapse = collapse) }
测试案例及异常表现
# 单个向量输入时结果符合预期 > MYpaste(c("", "b", "a", ""), collapse = " + ") [1] "b + a" > MYpaste(c("", "b", "a", ""), sep = " + ") [1] "b" "a" # 多个对象输入时结果异常 > MYpaste("", "b", "a", "", collapse = " + ") [1] "" # 预期结果应为"b + a" > MYpaste("", "b", "a", "", sep = " + ") character(0) # 预期结果应为"b + a"
问题根源
- 当
...传入多个对象时,as.list(...)会将每个对象作为列表的独立元素,x[x != ""]是在列表层面过滤空元素,而非元素内部的空字符串 - 直接将过滤后的列表传给
paste()时,paste会把整个列表当作单个参数处理,而非展开所有元素 - 若列表元素是长度大于1的向量,
x != ""会返回逻辑向量,导致列表索引逻辑出错
修复方案(两种可选)
方案1:合并所有元素后过滤空字符串
将...中所有输入(包括单个值和向量)合并为一个向量,过滤空字符串后再调用原生paste,适合需要统一过滤所有空值的场景:
MYpaste <- function(..., sep = "", collapse = NULL, recycle0 = FALSE) { # 合并所有输入元素为单个向量 all_elements <- unlist(list(...), use.names = FALSE) # 过滤空字符串 filtered <- all_elements[all_elements != ""] # 调用原生paste处理 paste(filtered, sep = sep, collapse = collapse, recycle0 = recycle0) }
测试验证:
> MYpaste("", "b", "a", "", collapse = " + ") [1] "b + a" > MYpaste("", "b", "a", "", sep = " + ") [1] "b + a" > MYpaste(c("", "b", "a", ""), collapse = " + ") [1] "b + a"
方案2:保留原生paste参数逻辑
先对...中每个元素单独过滤空字符串,再按原生paste的逻辑(比如多向量按位置循环拼接)处理,更贴近原生函数的行为:
MYpaste <- function(..., sep = " ", collapse = NULL, recycle0 = FALSE) { # 对每个输入元素单独过滤空字符串 args <- lapply(list(...), function(x) x[x != ""]) # 调用原生paste并传入处理后的参数 do.call(paste, c(args, list(sep = sep, collapse = collapse, recycle0 = recycle0))) }
测试验证:
> MYpaste("", "b", "a", "", sep = " + ") [1] "b + a" > MYpaste(c("", "b", "a", ""), c("x", "", "y"), sep = "-") [1] "b-x" "a-y" # 按位置拼接各自过滤后的元素
内容的提问来源于stack exchange,提问作者Adela
相关产品推荐
相关产品推荐

