使用ifelse()为数据框基于现有列创建新列的函数报错求助
问题解决:R语言cont_to_cat函数赋值错误修复
错误原因分析
你的代码存在两个核心问题:
- 动态列名赋值错误:
df$s会把s当成字面量列名(即创建名为s的列),而非变量s中存储的动态列名(比如cat_V1),这会导致后续赋值逻辑混乱。 - 目标列引用错误:
df$score_col是按字面量查找列名,而非使用参数score_col对应的列。因为score_col是字符串参数,df$score_col会试图寻找名为score_col的列,而你的测试数据框中没有这一列,因此返回空的逻辑向量(logical(0)),与原数据框的10行不匹配,触发报错。
修正后的代码(基础R版本)
# 测试数据框 df <- as.data.frame(matrix(runif(n=10, min=0, max=10), nrow=10)) cont_to_cat <- function(df, score_col){ s <- paste('cat_', score_col, sep='') # 使用[[s]]引用动态列名,用df[[score_col]]获取目标列的值 df[[s]] <- ifelse(df[[score_col]] <6, 'Rating: 6-', ifelse(df[[score_col]] >=6 & df[[score_col]] <7, 'Good: 6+', ifelse(df[[score_col]] >=7 & df[[score_col]] <8, 'Very good: 7+', ifelse(df[[score_col]] >=8 & df[[score_col]] <9, 'Fabulous: 8+', ifelse(df[[score_col]] >=9, 'Superb: 9+', 'NULL'))))) return(df) } new_df <- cont_to_cat(df, 'V1')
优化版本(使用dplyr的case_when,更易读)
如果你熟悉dplyr包,多层ifelse可以用case_when替代,逻辑更清晰:
library(dplyr) df <- as.data.frame(matrix(runif(n=10, min=0, max=10), nrow=10)) cont_to_cat <- function(df, score_col){ s <- paste('cat_', score_col, sep='') df <- df %>% mutate(!!s := case_when( .data[[score_col]] <6 ~ 'Rating: 6-', .data[[score_col]] >=6 & .data[[score_col]] <7 ~ 'Good: 6+', .data[[score_col]] >=7 & .data[[score_col]] <8 ~ 'Very good: 7+', .data[[score_col]] >=8 & .data[[score_col]] <9 ~ 'Fabulous: 8+', .data[[score_col]] >=9 ~ 'Superb: 9+', TRUE ~ 'NULL' )) return(df) } new_df <- cont_to_cat(df, 'V1')
这里!!s用于将变量s中的字符串作为列名,.data[[score_col]]用于引用动态列,符合tidyverse的语法规范。
内容的提问来源于stack exchange,提问作者Abdelkabir MENANI
相关产品推荐
相关产品推荐

