目标:将数据帧随机分成3个样本。
这是一个笨重的解决方案:
allrows <- 1:nrow(mtcars)
set.seed(7)
trainrows <- sample(allrows, replace = F, size = 0.6*length(allrows))
test_cvrows <- allrows[-trainrows]
testrows <- sample(test_cvrows, replace=F, size = 0.5*length(test_cvrows))
cvrows <- test_cvrows[-which(test_cvrows %in% testrows)]
train <- mtcars[trainrows,]
test <- mtcars[testrows,]
cvr <- mtcars[cvrows,]
必须有一些更容易的东西,也许在一个包中。 dplyr
具有sample_frac
功能,但这似乎针对单个样本,而不是分成多个样本。
关闭,但不是这个问题的答案: Random Sample with multiple probabilities in R
答案 0 :(得分:8)
你需要分区准确吗?如果没有,
set.seed(7)
ss <- sample(1:3,size=nrow(mtcars),replace=TRUE,prob=c(0.6,0.2,0.2))
train <- mtcars[ss==1,]
test <- mtcars[ss==2,]
cvr <- mtcars[ss==3,]
应该这样做。
或者,正如@Frank在评论中所说,您可以split()
原始数据将它们作为列表的元素:
mycars <- setNames(split(mtcars,ss), c("train","test","cvr"))
答案 1 :(得分:1)
不是最漂亮的解决方案(特别是对于较大的样本),但它确实有效。
file_uploads = On
upload_tmp_dir = /var/www/tmpdir/
upload_max_filesize = 1024M
答案 2 :(得分:0)
无需替换的选项
使用插入包。
library(caret)
inTrain <- createDataPartition(mtcars$mpg, p = 0.6, list = FALSE)
train <- mtcars[inTrain, ]
inTest <- createDataPartition(mtcars$mpg[-inTrain], list = FALSE)
test <- mtcars[-inTrain,][inTest, ]
cvr <- mtcars[-inTrain,][-inTest, ]
基础包。
## splitData
# y column of data to create split on
# p list of percentage split
splitData <- function(y, p = c(0.5)){
if(sum(p) > 1){
stop("sum of p cannot exceed 1")
}
rows <- 1:length(y)
res <- list()
n_sample = round(length(rows) * p)
for( size in n_sample){
inSplit <- sample.int(length(rows), size)
res <- c(res, list(rows[inSplit]))
rows <- rows[-inSplit]
}
if(sum(as.matrix(p)) < 1){
res <- c(res, list(rows))
}
res
}
split_example_2 <- splitData(mtcars$mpg, p = c(0.6, 0.2))
split_example_3 <- splitData(mtcars$mpg)
答案 3 :(得分:0)
如果您想获得每个组的准确且可复制的数字(请记住,组的大小必须是整数,并尽可能接近比例地分割),而不是每次允许组大小随机变化您执行随机分割时,请尝试:
sample_size <- nrow(mtcars)
set_proportions <- c(Training = 0.6, Validation = 0.2, Test = 0.2)
set_frequencies <- diff(floor(sample_size * cumsum(c(0, set_proportions))))
mtcars$set <- sample(rep(names(set_proportions), times = set_frequencies))
然后,您可以简单地通过以下方式将其拆分为数据帧列表
mtcars <- split(mtcars, mtcars$set)
例如验证集的数据框现在以mtcars$Validation
的形式访问,或者您也可以拆分为以下单独的数据框:
mtcars_train <- mtcars[mtcars$set == "Training", ]
mtcars_validation <- mtcars[mtcars$set == "Validation", ]
mtcars_test <- mtcars[mtcars$set == "Test", ]
在某些情况下,例如这种情况,您无法精确地拆分数据60%,20%,20%,但是这种方法保证了两个20%集的大小彼此之间不应超过一个:
> set_frequencies
Training Validation Test
19 6 7
检查它是否按预期工作:
> table(mtcars$set)
Test Training Validation
7 19 6
(基于Ben Bolker的回答和liori的评论。)