这可以很简单地实现。
library(tidyverse)
chars<-c("A","B","C","D")
complete_data <- tibble(v1=rnorm(100,2,100),
v2=rnorm(100,1,100),
v3=sample(chars, 100, replace=TRUE))
propCategory = function(data, category, prop){
category = enquo(category)
cat1 = data %>% pull(!!category)
unlist(sapply(as.list(unique(cat1)), function(x) {sample(which(cat1==x), sum(cat1==x)*prop)}))
}
complete_data %>% propCategory(v3, .2)
输出
[1] 98 35 20 78 40 70 87 3 86 38 22 100 80 93 47 5 24 29 26
如您所见,我的propCategory 函数返回轴向索引。但是让我们检查一下它们是否包含您需要的东西。
首先,让我们检查一下训练指标。
train = complete_data %>% propCategory(v3, .75)
complete_data[train,] %>% distinct(v3)
complete_data[train,] %>% nrow()
输出
> complete_data[train,] %>% distinct(v3)
# A tibble: 4 x 1
v3
<chr>
1 B
2 A
3 D
4 C
> complete_data[train,] %>% nrow()
[1] 74
现在是测试索引的时候了。
complete_data[-train,] %>% distinct(v3)
complete_data[-train,] %>% nrow()
输出
> complete_data[-train,] %>% distinct(v3)
# A tibble: 4 x 1
v3
<chr>
1 B
2 A
3 D
4 C
> complete_data[-train,] %>% nrow()
[1] 26
如您所见,训练和测试数据都包含您的每个类别。
关于prop 参数的一点说明。
我的 propCategory 函数的编写方式是,对于变量类别中的每个值,它返回带有 prop * 的随机选择索引的数量(分类变量的保存值的数量)。
仔细看看下面的结果。
complete_data %>% group_by(v3) %>%
summarise(n = n(), prop = n()/nrow(.))
complete_data[train,] %>% group_by(v3) %>%
summarise(n = n(), prop = n()/nrow(.))
complete_data[-train,] %>% group_by(v3) %>%
summarise(n = n(), prop = n()/nrow(.))
输出
> complete_data %>% group_by(v3) %>%
+ summarise(n = n(), prop = n()/nrow(.))
# A tibble: 4 x 3
v3 n prop
<chr> <int> <dbl>
1 A 26 0.26
2 B 35 0.35
3 C 24 0.24
4 D 15 0.15
> complete_data[train,] %>% group_by(v3) %>%
+ summarise(n = n(), prop = n()/nrow(.))
# A tibble: 4 x 3
v3 n prop
<chr> <int> <dbl>
1 A 19 0.257
2 B 26 0.351
3 C 18 0.243
4 D 11 0.149
> complete_data[-train,] %>% group_by(v3) %>%
+ summarise(n = n(), prop = n()/nrow(.))
# A tibble: 4 x 3
v3 n prop
<chr> <int> <dbl>
1 A 7 0.269
2 B 9 0.346
3 C 6 0.231
4 D 4 0.154