您可以使用 map_dfr 而不是来自 purrr 库的 lapply(在执行下一步之前,请务必考虑到您需要 install.package("purr") 和 library(purrr)。但也许您已经安装了它,因为它是一个通用软件包。
然后你可以使用下一个代码
dat2$rowid<-1:nrow(dat2)
dat_discharge <- split(dat2,dat2$id)
trainList<- dat_discharge %>% map_dfr(.f=function(x){
sampling <- sample(1:nrow(x),round(0.75*nrow(x),0))
result <- x[sampling,]
})
testL<-dat2[!(dat2$rowid %in% trainList$rowid),]
解释上面的代码。首先,我向 dat2 添加了一个唯一的 rowid,这样我就知道我在采样哪些行,哪些不采样。这将在最后一行代码中用于区分 Test 和 Train 数据集,例如 Train dataset 没有 test 所具有的任何 rowid。
然后我像你一样进行拆分以创建 dat_discharge
然后对 dat_discharge 列表中的每个数据帧,我应用 map_dfr 中的函数。 map_dfr 功能与 lapply 相同,只是它将输出“连接”在单个数据帧中,而不是像 lapply 那样将每个输出放入列表中。前提是 map_dfr 的每次迭代的输出是与第一次迭代具有相同列的数据帧。把它想象成“好的,我得到了这个数据帧,我要把它的行绑定到前一个数据帧结果”。所以结果只是一个大数据框。
在该函数中,您会注意到我正在做的示例有点不同。我取了迭代数据帧所具有的行数序列的 75%,然后,使用该采样序列,我使用 x[sampling,] 对迭代数据帧进行子集化,并为该迭代生成我的采样数据帧(这是其中一个dat_discharge 列表中的数据帧)。并且,map_dfr 会自动将每个结果的采样数据帧连接到一个单独的大数据帧中,而不是像 lapply 那样将它们放在一个列表中。
所以最后,我只是将测试创建为 dat2 中不存在于测试集中的所有 rowid。
希望这个服务器你好:)
请注意,如果您想为每个 id 抽取 75% 的观察值,那么每个 id 应该至少有 4 个观察值才能有意义。想象一下,如果您在特定 id 中只有 1 个观察值,哎呀!这段代码仍然可以工作(它只会选择那个观察值),但是当你构建你的统计模型时,你真的需要考虑这个含义