如何将Python生成分类哑变量的代码转换为R高效实现?
问题描述
需要将以下Python代码转换为高效的R实现:
for genre in c_a: df['is_'+str(genre)] = df['genre'].apply(lambda x: genre in [y.strip() for y in x.split(',')])
具体需求:基于一个包含1341个值的字符向量c_a,为数据框新增对应列,判断每个genre是否存在于Genre列的逗号分隔内容中,为新列赋值0或1。当前用for循环实现效率较低,寻求更高效方案。
示例输入
| Genre |
|---|
| dance pop, pop |
| country, pop |
期望输出
| Genre | dance pop | pop | country |
|---|---|---|---|
| dance pop, pop | 1 | 1 | 0 |
| country, pop | 0 | 1 | 1 |
高效解决方案
方法1:使用tidyverse生态(易读性高)
利用tidyr和dplyr的向量化操作替代循环,适合处理复杂数据场景:
library(tidyverse) # 替换为你的实际数据框和字符向量 df <- tibble(Genre = c("dance pop, pop", "country, pop")) c_a <- c("dance pop", "pop", "country") result <- df %>% # 添加行索引用于后续合并 mutate(row_id = row_number()) %>% # 将Genre列按逗号拆分到多行 separate_rows(Genre, sep = ",\\s*") %>% # 标记存在的genre为1 mutate(value = 1) %>% # 转换为宽表,不存在的genre填充0 pivot_wider( id_cols = row_id, names_from = Genre, values_from = value, values_fill = 0, # 确保c_a中的所有genre都生成对应列 names_expand = TRUE, names_sort = TRUE ) %>% # 合并回原数据并移除行索引 right_join(df %>% mutate(row_id = row_number()), by = "row_id") %>% select(-row_id, everything())
方法2:使用Base R(轻量高效)
利用向量化的字符串匹配函数grepl,底层为C实现,处理大量数据速度更快:
# 替换为你的实际数据框和字符向量 df <- data.frame(Genre = c("dance pop, pop", "country, pop"), stringsAsFactors = FALSE) c_a <- c("dance pop", "pop", "country") # 构建正则表达式,确保匹配完整的genre(避免部分匹配) patterns <- paste0("(^|,\\s*)", c_a, "(,\\s*|$)") # 批量生成所有genre标记列 genre_columns <- sapply(patterns, function(pattern) as.integer(grepl(pattern, df$Genre))) # 合并到原数据框并设置列名 result <- cbind(df, genre_columns) colnames(result)[-1] <- c_a
说明:两种方法都避免了低效的逐行循环,其中Base R方法无需加载额外包,适合对性能要求较高的场景;tidyverse方法代码更直观,便于后续维护和扩展。
内容的提问来源于stack exchange,提问作者Yvette
相关产品推荐
相关产品推荐

