You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用递归函数构建嵌套ifelse调用并正确替换data参数?

递归构建嵌套ifelse的元编程解决方案

我想要编写一个递归函数来构建嵌套的ifelse调用,虽然清楚有dplyr::case_when、data.table::fcase这类更简洁的替代方案,但核心目的是学习如何用元编程解决这类问题。

目前的代码可以生成嵌套的ifelse结构,但无法将代码中的data替换为实际传入的参数(例如my_df)。如果把quote(data)替换成substitute(data),只有第一层ifelse能正确替换,进入下一次迭代后又会变回data。我知道pryr::modify_lang可以事后解决这个问题,但希望找到base R原生的解决方案。

初始代码如下:

my_df <- data.frame(group = letters[1:3],
                    value = 1:3)

build_ifelse <- function(data, by, values, iter=1){
  
  x <- call("ifelse",
            call("==",
                 call("[[", quote(data), by),
                 values[iter]),
            1,
            if(iter != length(values)) build_ifelse(data, by, values, iter = iter + 1) else NA)
  return(x)
}

build_ifelse(data = my_df, by = "group", values = letters[1:3])
# ifelse(data[["group"]] == "a", 1, ifelse(data[["group"]] == "b", 
#        1, ifelse(data[["group"]] == "c", 1, NA)))

找到的解决方案

通过参考相关思路,我得到了一个效果很好的base R解决方案:

build_ifelse <- function(data, by, values, iter=1){
  
  x <- call("ifelse",
            call("==",
                 call("[[", quote(data), by),
                 values[iter]),
            1,
            if(iter != length(values)) build_ifelse(data, by, values, iter = iter + 1) else NA)
  
  x <- do.call(what = "substitute",
               args = list(x, 
                           list(data = substitute(data))))
  return(x)
}

build_ifelse(data = my_df, by = "group", values = letters[1:3])
# ifelse(my_df[["group"]] == "a", 1, ifelse(my_df[["group"]] == 
#     "b", 1, ifelse(my_df[["group"]] == "c", 1, NA)))

eval(build_ifelse(data = my_df, by = "group", values = letters[1:3]))
# [1] 1 1 1

内容的提问来源于stack exchange,提问作者Hutch3232

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:15:47