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

R语言中setdiff()无数据显示:决策树训练集异常问题

问题描述

我尝试用决策树预测药物类别,设置随机种子后用sample_frac()划分训练集,再用setdiff()生成测试集。遇到异常情况:明明能确认训练集数据存在,但查看data_test时显示无数据,不过决策树依然可以正常生成。

相关代码
data <- data %>% select(BP, Cholesterol, Drug)
view(data)
str(data)

data <- lapply(data, as.factor)
data <- lapply(data, as.numeric)
view(data)

data <- as.data.frame(data)
view(data)

set.seed(111)
data_training <- data %>% sample_frac(0.80)
data_test <- data %>% setdiff(data_training)

view(data_training)
view(data_test)

data_tree <- rpart(Drug ~ BP + Cholesterol, data=data_training, method = 'class')
plot(data_tree, uniform=TRUE, margin=0.5)
text(data_tree, use.n = TRUE)

data_test['Predicted'] <- predict(data_tree, data_test, type = 'class')
view(data_test)
问题原因
  1. setdiff()的逻辑不适合拆分数据集:setdiff()是按行内容进行差集计算,而非按行索引拆分。如果原数据存在重复行,它会把所有与训练集内容重复的行从测试集中移除,直接导致测试集为空;即使没有重复行,这种方式也不是标准的数据集拆分逻辑。
  2. 数据类型转换的冗余操作:两次lapply将数据框转为列表后再转回数据框,虽然最终结果是数据框,但中间步骤可能导致数据结构临时异常,不过核心问题还是setdiff()的使用错误。
解决方法

方法1:按索引拆分数据集(推荐)

通过生成随机索引拆分,能保证数据拆分的准确性,不受重复行影响:

set.seed(111)
# 生成训练集索引
train_idx <- sample(nrow(data), size = 0.8 * nrow(data))
data_training <- data[train_idx, ]
# 用负索引取测试集
data_test <- data[-train_idx, ]

方法2:用anti_join()替代setdiff()(dplyr风格)

anti_join()会保留原数据中所有不在训练集里的行,匹配逻辑更适合数据集拆分:

set.seed(111)
data_training <- data %>% sample_frac(0.8)
data_test <- data %>% anti_join(data_training)

方法3:简化数据类型转换

原代码的类型转换可以简化为数据框内的批量操作,避免转为列表的步骤:

data <- data %>% 
  select(BP, Cholesterol, Drug) %>%
  # 批量将所有列转为因子后再转数值
  mutate(across(everything(), ~ as.numeric(as.factor(.x))))

内容的提问来源于stack exchange,提问作者Dan C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:31:02