R语言房屋销售数据清洗代码纠错与变量类型定义咨询
R语言数据清洗代码错误排查与优化建议
核心疑问解答
- Nominal类型列是否必须用factor()定义?
不是强制要求,但非常推荐。字符型(chr)也能存储名义变量,但转为factor后可以明确枚举所有合法类别,避免后续分析(如统计建模)中出现意外的无效字符值,同时还能节省内存。如果任务输出要求city保持chr类型,那可以不转,但从规范的数据分析流程来说,转factor更严谨。 - Continuous、Discrete、Ordinal列需要指定对应类型吗?
- 连续型(Continuous):R中数值默认是double类型,完全满足需求,无需额外指定,除非有特殊精度要求。
- 离散型(Discrete):如果是整数类离散值(如卧室数bedrooms),建议保留integer类型;如果经过均值填充等操作转为double,可通过
as.integer()强制转回integer,更符合离散型变量的定义。 - 有序型(Ordinal):必须用
factor()并指定levels参数定义顺序,这是区分有序和名义变量的核心,你代码里这部分处理是正确的。
- 标注为Discrete的sale_date列该设为date还是int类型?
从业务逻辑和数据分析实用性来看,日期属于有序离散值,更适合转为Date类型(用as.Date()),而非chr或int。Date类型支持日期运算(如计算间隔、排序),比字符型更实用;如果任务硬性要求输出chr类型,那按要求执行,但优先推荐用Date类型。
代码问题排查
对比原始数据和目标输出结构,你的代码存在以下问题:
- area精度不符合要求:目标输出中
area是整数(如108),但你的代码用round(...,1)保留一位小数,与目标不符,需改为取整。 - sale_date类型未优化:目标输出是chr类型,但从数据分析角度,未转为
Date类型会限制后续日期相关操作;若任务允许,建议转为Date类型。 - bedrooms类型可优化:目标输出是num类型,但卧室数是整数离散值,转为integer类型更合理。
- 数据处理顺序可调整:先过滤无效行(如sale_price缺失/负值)再去重,能减少不必要的计算量。
- house_type替换效率低:多次调用
str_replace,可以合并为一次str_replace_all,代码更简洁。 - 均值计算重复:在
mutate中多次计算均值,会重复遍历数据,提前计算均值能提升效率。
优化后的代码
library(dplyr) library(stringr) # 读取数据,关闭默认转factor house_sales <- read.csv("Downloads/house_sales.csv", stringsAsFactors = FALSE) # 提前计算所需均值,避免重复计算 mean_months <- mean(house_sales$months_listed, na.rm = TRUE) mean_bedrooms <- round(mean(house_sales$bedrooms, na.rm = TRUE)) mean_area <- round(mean(as.numeric(gsub(" sq.m.", "", house_sales$area)), na.rm = TRUE)) clean_data <- house_sales %>% # 先过滤无效的sale_price行 filter(!is.na(sale_price), sale_price >= 0) %>% # 移除重复house_id distinct(house_id, .keep_all = TRUE) %>% # 处理city缺失值 mutate(city = case_when( is.na(city) | city == "--" ~ "Unknown", TRUE ~ city )) %>% # sale_price转为double(符合目标输出) mutate(sale_price = as.double(sale_price)) %>% # sale_date转为Date类型(若任务要求chr,可注释这部分) mutate(sale_date = as.Date(sale_date)) %>% mutate(sale_date = ifelse(is.na(sale_date), as.Date("2023-01-01"), sale_date)) %>% mutate(sale_date = as.Date(sale_date, origin = "1970-01-01")) %>% # 填充months_listed缺失值并保留一位小数 mutate(months_listed = round(ifelse(is.na(months_listed), mean_months, months_listed), 1)) %>% # 填充bedrooms缺失值并转为integer mutate(bedrooms = ifelse(is.na(bedrooms), mean_bedrooms, bedrooms)) %>% mutate(bedrooms = as.integer(bedrooms)) %>% # 批量替换house_type缩写并转为有序factor mutate(house_type = str_replace_all(house_type, c( "^Det\\.$" = "Detached", "^Semi$" = "Semi-detached", "^Terr\\.$" = "Terraced" ))) %>% mutate(house_type = factor(house_type, levels = c("Terraced", "Semi-detached", "Detached"), ordered = TRUE)) %>% # 提取area数值、填充缺失值并取整 mutate(area = as.numeric(gsub(" sq.m.", "", area))) %>% mutate(area = ifelse(is.na(area), mean_area, area)) %>% mutate(area = as.integer(round(area, 0))) # 验证结果结构 str(clean_data)
优化说明
- 提前计算均值,减少
mutate中的重复计算,提升代码效率。 - 用
case_when替代ifelse,处理多条件缺失值更清晰易读。 - 用
str_replace_all批量替换house_type缩写,简化代码结构。 - 调整数据处理顺序,先过滤无效行再去重,减少计算量。
- 将
sale_date转为Date类型,增强数据的可分析性;若任务要求chr类型,可注释相关转换代码。 - 明确
bedrooms和area的整数类型,更符合离散型变量的定义。
内容的提问来源于stack exchange,提问作者TMM
相关产品推荐
相关产品推荐

