如何用递归函数构建嵌套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
相关产品推荐
相关产品推荐

