从数据帧开始并以数据帧结束时避免中间 dlply 步骤

Avoiding intermediate dlply step when starting with a dataframe and ending with a dataframe

我正在使用 plyr 对数据集的子集执行引导函数。

因为 boot 函数创建了一个列表对象,我目前使用 dlply 来存储函数的输出,然后使用 ddply 来获取我想要的 bootfunction 部分

我的示例数据集如下:

dat = data.frame(x = rnorm(10, sd = 1),y = rnorm(10, sd = 1),z = rep(c("SppA", "SppB", "SppC", "SppD", "SppE"), 2),u = rep(c("SiteA", "SiteB"), 5))

确切的函数并不是特别重要,但为了可重复性,这里是我使用的函数:

boot_fun = function(x,i) {
  i = sample(1:24, 24, replace = TRUE)
  ts1 = mean(x[i,"x"])
  ts2 = sample(x[i,"y"])
  mean(ts1) - mean(ts2)
}

我的 plyr 函数如下:

temp = dlply(dat, c("z", "u"), summarise, boot_object = boot(dat, boot_fun, R = 1000))

因为我想从 boot 对象中得到的是 mean 和 CI,所以我执行以下 plyr 函数:

temp2 = ldply(temp, summarise, mean = mean(boot$t), lowCI = quantile(boot$t, 0.025), highCI = quantile(boot$t, 0.975))

这确实有效并完成了我想要的(尽管关于子集的错误似乎并不影响我关心的任何事情),但我觉得应该有一种方法可以跳过中间的 dlply 步骤.

-edit- 澄清如果我不需要拆分组我想做什么

如果我是手动分割而不是使用 plyr,它看起来会像下面这样:

temp = boot(dat[dat$z == "SppA" & dat$u == "SiteA",], boot_fun, R = 1000)
temp2$mean = mean(temp$t)
temp2$lowCI = quantile(temp$t, 0.025)
temp2$highCI = quantile(temp$t, 0.975)

如果我根本不关心小组,只想对整个小组这样做,那就是

temp = boot(dat, boot_fun, R = 1000)
temp2$mean = mean(temp$t)
temp2$lowCI = quantile(temp$t, 0.025)
temp2$highCI = quantile(temp$t, 0.975)

我无法重现你的例子。

当我执行 temp = boot(dat, boot_fun, R = 1000) 时,我得到 WARNING:

ORDINARY NONPARAMETRIC BOOTSTRAP
Call:
boot(data = dat, statistic = boot_fun, R = 1000)
Bootstrap Statistics :
WARNING: All values of t1* are NA

我认为您当前的代码非常高效,但如果您正在寻找其他可能性,您可以尝试 tidyverse1) group_by相关列,2) nest bootstrapping 的相关数据,3) 运行 你的bootstrap 与嵌套数据,4) 隔离你想要的统计数据,然后 5) return 到 正常数据帧

library(boot)
library(tidyverse)
dat1 <- dat %>%
          group_by(z,u) %>%
          nest() %>%
          mutate(data=map(data,~boot(.x, boot_fun, R=1000))) %>%
          mutate(data=map(data,~data.frame(mean=mean(.x$t), lowCI=quantile(.x$t, 0.025), highCI=quantile(.x$t,0.975)))) %>%
          unnest(data)