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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:17:35