如何在 R 中使用 lapply 对包含多个数据帧的列表进行采样?

How to sample a list containing multiple dataframes using lapply in R?

我有这个数据列表,是我通过在数据帧上使用拆分创建的:

dat_discharge = split(dat2,dat2$discharge_id)

我正在尝试通过抽样从该数据列表创建训练集和测试集,以考虑数据中根本不均匀分布的出院 ID 组。

我正在尝试使用 lapply 来执行此操作,因为我不想单独对列表中的每个组进行抽样。

trainlist<-lapply(dat_discharge,function(x) sample(nrow(x),0.75*nrow(x))) 

trainL =  dat_discharge[(dat_discharge %in% trainlist)]
testL = dat_discharge[!(dat_discharge %in% trainlist)]

我尝试模拟此 post (R removing items in a sublist from a list) 以创建测试和训练子集,但是训练列表完全是空的,我认为这不是正确的方法那是一个数据帧列表?

如果不选择列表中的单个数据帧,我想要做的事情是否可行,例如 data_frame[[1]]?

您可以使用 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,这样我就知道我正在采样哪些行,哪些不是。这将在最后一行代码中用于区分测试和训练数据集,例如训练数据集没有测试具有的任何 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 个观察,哎呀!。这段代码仍然有效(它只是 select 那个观察),但是当你构建你的统计模型时你真的需要考虑这个含义