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

如何在R中基于列单元格内的多值创建虚拟变量

解决方案:为食谱食材生成虚拟变量并保留原数据列

原代码存在的问题

  • 变量名错误:unlist(t)中的t未定义,实际应为你创建的final;names(final2) <- item中的item应为大写的Item(R语言区分大小写)
  • 未将生成的虚拟变量与原数据集合并,导致丢失原有列
  • 使用grepl匹配食材可能出现误判(例如grepl("cream", "cream cheese")会返回TRUE,导致"cream"和"cream cheese"的虚拟变量被错误标记)
  • 未处理食材字符串前后的空格,导致拆分后食材名不一致(比如" vinegar"和"vinegar"会被视为不同食材)

方案一:使用tidyverse工具链(简洁直观)

依赖dplyr和tidyr包,通过拆分-转宽的方式生成虚拟变量,同时保留所有原列:

library(dplyr)
library(tidyr)
library(stringr)

# 处理数据并生成结果
cookbooks_result <- cookbooks4 %>%
  # 添加行号用于后续合并匹配
  mutate(row_id = row_number()) %>%
  # 将逗号分隔的食材拆分为单独行
  separate_rows(Item, sep = ",") %>%
  # 去除食材名称前后的空格
  mutate(Item = str_trim(Item)) %>%
  # 标记当前行的食材存在(值为1)
  mutate(has_ingredient = 1) %>%
  # 转换为宽表,每个食材作为列,不存在的食材填0
  pivot_wider(
    id_cols = row_id,
    names_from = Item,
    values_from = has_ingredient,
    values_fill = 0
  ) %>%
  # 与原数据集合并
  left_join(cookbooks4 %>% mutate(row_id = row_number()), by = "row_id") %>%
  # 移除临时行号,调整列顺序(原列在前,虚拟变量列在后)
  select(-row_id) %>%
  select(names(cookbooks4), everything())

方案二:基础R实现(高效轻量)

无需额外复杂依赖,适合处理大规模数据集:

library(stringr)

# 1. 拆分食材列并清理空格
item_split <- strsplit(cookbooks4$Item, split = ",")
item_split <- lapply(item_split, str_trim)

# 2. 获取所有唯一食材名称
unique_ingredients <- unique(unlist(item_split))

# 3. 生成虚拟变量矩阵:检查每行是否包含对应食材
dummy_matrix <- sapply(unique_ingredients, function(ing) {
  sapply(item_split, function(row_ings) as.integer(ing %in% row_ings))
})

# 4. 合并原数据与虚拟变量矩阵
cookbooks_result <- cbind(cookbooks4, dummy_matrix)

关键说明

  • 两种方案都处理了食材名称的空格问题,避免因空格导致的食材识别错误
  • 使用%in%替代grepl进行匹配,确保只有完全匹配的食材才会被标记为1,避免子串误判
  • 最终结果会保留原数据集的所有列,并在后方添加每个唯一食材对应的虚拟变量列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:20:26