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

使用apply与regexpr为DataFrame新增多列的技术求助

嘿,我来帮你搞定这个给DataFrame批量生成颜色标记列的需求!先从模拟你的数据场景开始,再给你两种靠谱的实现方法,顺便聊聊你用regexpr可能踩的坑。

先模拟你的数据场景

假设你的DataFrame和颜色列表是这样的:

# 模拟原始DataFrame
df <- data.frame(
  product_id = c(1, 2, 3),
  colors = c("红色,蓝色", "绿色,红色", "黄色")
)

# 你的目标颜色列表
target_colors <- c("红色", "蓝色", "绿色", "黄色")

方法1:用tidyverse(直观易读,适合复杂数据操作)

如果习惯用tidyverse工具链,这个方法逻辑清晰,一步到位就能生成你要的结果:

library(tidyverse)

df_result <- df %>%
  # 把逗号分隔的颜色拆成每行一个
  separate_rows(colors, sep = ",") %>%
  # 标记该颜色存在为1
  mutate(exists = 1) %>%
  # 转成宽表,缺失的颜色自动补0
  pivot_wider(
    names_from = colors,
    values_from = exists,
    values_fill = 0
  )

print(df_result)

运行后会得到你想要的输出:

# A tibble: 3 × 5
  product_id   红色   蓝色   绿色   黄色
       <dbl> <dbl> <dbl> <dbl> <dbl>
1          1     1     1     0     0
2          2     1     0     1     0
3          3     0     0     0     1

方法2:用Base R(轻量无需额外包)

如果不想加载tidyverse,用Base R的lapply结合grepl也能实现,这应该和你尝试的方向接近:

df_base <- df
# 遍历颜色列表,给每个颜色生成一列0/1标记
df_base[target_colors] <- lapply(target_colors, function(color) {
  # grepl检查是否包含该颜色,转成整数0/1
  as.integer(grepl(color, df_base$colors, fixed = TRUE))
})

print(df_base)

这里要注意fixed = TRUE,它会把颜色当成纯文本匹配,避免因为颜色里有正则特殊字符(比如.、*)导致的意外匹配——这可能是你之前用regexpr出错的原因之一!

修复你用regexpr的尝试

如果坚持想用regexpr,只要把匹配结果转换成0/1,同时加上fixed = TRUE就能正常运行了:

df_regex <- df
df_regex[target_colors] <- lapply(target_colors, function(color) {
  # regexpr返回匹配位置,>0表示存在,转成0/1
  as.integer(regexpr(color, df_regex$colors, fixed = TRUE) > 0)
})

两种方法都能生成你要的结果,选哪种看你的习惯就行~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:29:56