如何在dplyr::mutate中传递字符串作为列名实现标签映射?
问题描述
有一个包含调查选项列choices与选择索引列choice的dataframe,示例数据如下:
df <- tibble( record_id = 1:9, choices = c(rep("1, A | 2, B | 3, C", 3), rep("1, Apple | 2, Banana | 3, Cherry", 3), rep("1, America | 2, Belgium | 3, China", 3)), choice = sample(1:3, size = 9, replace = T) )
目标是根据choices列中的标签映射生成label列。已编写make_key函数,单独调用可正常运行:
make_key <- function(.str) { lstr <- str_split(.str, pattern = " \\| ") out <- map(lstr, ~str_remove(.x, pattern = "^([0-9]+), ")) %>% as_vector() out_names <- map(lstr, ~str_extract(.x, pattern = "^([0-9]+)")) %>% as_vector() names(out) <- out_names return(out) } # 正常运行示例: my_string <- c("1, A | 2, B | 3, C") recode(1, !!!make_key(my_string)) # [1] "A"
但在rowwise管道中调用dplyr::mutate时出现报错:
rowwise(df) %>% mutate(label = recode(choice, !!!make_key(choices)) ) # Error in stri_split_regex(string, pattern, n = n, simplify = simplify, : # object 'choices' not found
尝试过添加双大括号{{}}及rlang相关函数,均未解决问题,寻求可行解决方案。
解决方案
方法1:用purrr::map2逐行配对处理
无需依赖rowwise,直接用map2_chr将choice和choices逐组传入,结合原make_key函数完成匹配:
library(dplyr) library(purrr) library(stringr) df <- df %>% mutate(label = map2_chr(choice, choices, function(ch, str) { key <- make_key(str) recode(ch, !!!key) }))
方法2:整合匹配逻辑到函数,适配rowwise
修改函数逻辑,让它直接接收索引和选项字符串并返回对应标签,避免非标准求值的环境问题:
get_label <- function(choice_idx, choices_str) { split_str <- str_split(choices_str, " \\| ")[[1]] idx <- str_extract(split_str, "^\\d+") %>% as.integer() labels <- str_remove(split_str, "^\\d+, ") labels[match(choice_idx, idx)] } df <- df %>% rowwise() %>% mutate(label = get_label(choice, choices)) %>% ungroup()
方法3:用tidyr拆分后匹配(无自定义函数)
先拆分choices列提取索引与标签,再通过关联匹配生成结果,逻辑更直观:
library(tidyr) df_label <- df %>% select(record_id, choices) %>% separate_rows(choices, sep = " \\| ") %>% mutate( choice_idx = str_extract(choices, "^\\d+") %>% as.integer(), label = str_remove(choices, "^\\d+, ") ) %>% select(-choices) df <- df %>% left_join(df_label, by = c("record_id", "choice" = "choice_idx"))
内容的提问来源于stack exchange,提问作者sometimes_sci
相关产品推荐
相关产品推荐

