【问题标题】:Using dplyr to summarise a running total of distinct factors使用 dplyr 总结不同因素的运行总数
【发布时间】:2017-03-14 06:17:05
【问题描述】:

我正在尝试为相机诱捕调查生成物种饱和度曲线。我有成千上万的观察结果,并且在 dplyr 中进行了大部分操作。

我有三个野外地点,有几个星期诱捕的不同动物物种的观察记录。在某些星期没有动物,在其他星期可能有不止一个物种。我想为每个站点生成一个单独的数字,以比较在连续几周的研究中遇到新物种的速度。一旦在该地区捕获了总物种多样性,这些对新物种的观察最终应该会饱和。一些现场站点可能比其他站点更快地饱和。

问题是我还没有找到一种方法来计算不同物种的数量来提供按时间计算的总数。下面是一个简单的虚拟数据集。

field_site<-c(rep("A",4),rep("B",4),rep("C",4))
week<-c(1,2,2,3,2,3,4,4,1,2,3,4)
animal<-c("dog","dog","cat","rabbit","dog","dog","dog","rabbit","cat","cat","rabbit","dog")
df<-as.data.frame(cbind(field_site,week,animal),head=TRUE)

我可以很容易地生成每周分组中独特物种的数量,例如

tbl_df(df)%>%
  group_by(field_site,week) %>%
  summarise(no_of_sp=n_distinct(animal))

但这对在接下来的几周内再次遇到某些物种这一事实并不敏感。我真正需要的是对不同物种的运行计数,从第 1 周开始逐行计算每个站点的独特物种,假设数据是通过从调查开始开始增加时间进行排序的。

在现场 A 的示例中,在研究过程中按周遇到的物种累积总数为:第 1 周 = 1 个物种,第 2 周 = 2 个物种,第 3 周 = 3 个物种,第 4 周 = 仍然是 3物种。

对于站点 B,物种的累计总数为:第 1 周 = 0 个物种,第 2 周 = 1 个物种,第 3 周 = 1 个物种,第 4 周 = 1 个物种,等等...

任何建议将不胜感激。 提前欢呼!

【问题讨论】:

  • 站点 B 不是第 4 周 = 2 个物种,“狗”和“兔子”吗?

标签: r dplyr distinct-values cumulative-sum


【解决方案1】:

我做了两个假设:

  1. 站点 B,第 4 周 = 2 个物种,“狗”和“兔子”;和
  2. 所有站点共享相同的周,因此如果至少一个站点有第 4 周,那么所有站点都应该包含它。这只会驱动 mt(空)变量,请随时更新此变量。

我首先建议使用“空”data.frame 来确保网站填充了必要的周数:

mt <- expand.grid(field_site = unique(ret$field_site),
                  week = unique(ret$week))

tidyr 的使用有助于:

library(tidyr)

df %>%
  mutate(fake = TRUE) %>%
  # ensure all species are "represented" on each row
  spread(animal, fake) %>%
  # ensure all weeks are shown, even if no species
  full_join(mt, by = c("field_site", "week")) %>%
  # ensure the presence of a species persists at a site
  arrange(week) %>%
  group_by(field_site) %>%
  mutate_if(is.logical, funs(cummax(!is.na(.)))) %>%
  ungroup() %>%
  # helps to contain variable number of species columns in one place
  nest(-field_site, -week, .key = "species") %>%
  group_by(field_site, week) %>%
  # could also use purrr::map in place of sapply
  mutate(n = sapply(species, sum)) %>%
  ungroup() %>%
  select(-species) %>%
  arrange(field_site, week)
# # A tibble: 12 × 3
#    field_site   week     n
#        <fctr> <fctr> <int>
# 1           A      1     1
# 2           A      2     2
# 3           A      3     3
# 4           A      4     3
# 5           B      1     0
# 6           B      2     1
# 7           B      3     1
# 8           B      4     2
# 9           C      1     1
# 10          C      2     1
# 11          C      3     2
# 12          C      4     3

【讨论】:

  • 感谢@r2evans 非常明确的回答。是的,您的上述两个假设都是正确的,一切都说得通。然而,在将这种方法应用于我的完整数据集时,我遇到了一个问题。在实际研究中对动物的观察通常在每个观察期出现不止一个(在这种情况下是几周,但我的数据也可以组织成月和日)。这会在 expand.grid 方法的 full_join 阶段产生问题。它返回“错误:行(1、2、3、4、5)的重复标识符,......”关于如何解决这个问题的任何想法?
  • 您能否更新您的示例数据以反映此类事件?
  • 当然@r2evans,这里是站点 A 第 2 周额外“狗”观察结果的更新,以及站点 B 第 3 周额外“兔子”观察结果的更新。field_site
  • 尝试在管道的早期添加distinct()
  • 这回答了您的问题吗?如果是,请“接受”答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
相关资源
最近更新 更多