【问题标题】:How to sample a list containing multiple dataframes using lapply in R?如何在 R 中使用 lapply 对包含多个数据帧的列表进行采样?
【发布时间】:2021-03-02 20:01:30
【问题描述】:

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

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)]

我尝试模拟这篇文章 (R removing items in a sublist from a list) 以创建测试和训练子集,但是训练列表完全为空,我认为这意味着对于数据帧列表来说这不是正确的方法?

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

【问题讨论】:

    标签: r list sampling


    【解决方案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,这样我就知道我在采样哪些行,哪些不采样。这将在最后一行代码中用于区分 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 个观察值,哎呀!这段代码仍然可以工作(它只会选择那个观察值),但是当你构建你的统计模型时,你真的需要考虑这个含义

    【讨论】:

    • 这正是我想要的。感谢您的帮助和解释。您对采样率也提出了很好的看法。老实说,我更愿意将东西保存在列表中,但这并不是什么大问题,因为我可以再次将 dfs 放入列表中。非常感谢您的帮助!
    • 很高兴为您提供帮助,是的,您可以在火车上再次使用 split 并测试数据框以将它们作为列表返回。只是在stackoverflow中的一个友好提醒,如果您觉得您的问题已解决,您可以单击解决您问题的答案左上角的复选标记(靠近向上和低箭头)关闭它,这很重要,以便案例为未来遇到类似问题的人解决了状态。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    相关资源
    最近更新 更多