R语言循环批量生成哑变量报错问题求助
解决批量创建哑变量的循环报错问题
错误原因
- 动态列名赋值方式错误:
$运算符仅支持直接指定固定列名,不能嵌套paste0()这类函数生成动态列名,必须改用方括号[]索引的方式完成动态列赋值。 - 列名列表定义错误:原代码中
position_list用list()存储的是未定义变量,实际应该存储字符串形式的列名前缀。
修正后的可运行代码
# 改为字符串向量存储列名前缀 position_list <- c("imagetag_object_video", "imagetag_logo_video", "textvalue_video") for (x in position_list) { # 用方括号索引动态生成的列名 new_df2[paste0(x, "_Position_Center")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "CENTER", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Center_Right")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "CENTER_RIGHT", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Center_Left")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "CENTER_LEFT", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Top_Center")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "TOP_CENTER", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Top_Right")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "TOP_RIGHT", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Top_Left")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "TOP_LEFT", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Bottom_Center")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "BOTTOM_CENTER", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Bottom_Right")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "BOTTOM_RIGHT", na.rm=TRUE) >= 1, 1, 0) new_df2[paste0(x, "_Position_Bottom_Left")] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == "BOTTOM_LEFT", na.rm=TRUE) >= 1, 1, 0) # 删除原位置列 new_df2 <- select(new_df2, -contains(paste0(x, "_position"), ignore.case=FALSE)) }
进一步优化(减少重复代码)
把所有位置值提取为单独向量,通过嵌套循环进一步简化代码:
library(stringr) # 需先加载字符串处理包 position_list <- c("imagetag_object_video", "imagetag_logo_video", "textvalue_video") position_values <- c("CENTER", "CENTER_RIGHT", "CENTER_LEFT", "TOP_CENTER", "TOP_RIGHT", "TOP_LEFT", "BOTTOM_CENTER", "BOTTOM_RIGHT", "BOTTOM_LEFT") for (x in position_list) { for (pos in position_values) { # 把位置值转为驼峰式列名(比如CENTER转为Position_Center) col_name <- paste0(x, "_", gsub("_", " ", pos) %>% str_to_title() %>% str_replace_all(" ", "_")) new_df2[col_name] <- ifelse(rowSums(new_df2[,startsWith(names(new_df2), paste0(x, "_position"))] == pos, na.rm=TRUE) >= 1, 1, 0) } # 删除原位置列 new_df2 <- select(new_df2, -contains(paste0(x, "_position"), ignore.case=FALSE)) }
内容的提问来源于stack exchange,提问作者Jess
相关产品推荐
相关产品推荐

