Использование dplyr для подведения итогов различных факторов

Я пытаюсь построить кривую насыщенности видов для съемки с помощью камеры. У меня тысячи наблюдений и большинство манипуляций делаю в 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 недели, проходя вниз по строкам, предполагая, что данные сортируются путем увеличения времени с начала опроса.

Совокупное количество видов, встреченных в ходе исследования по неделям в примере для поля Участок А, будет: 1 неделя = 1 вид, 2 неделя = 2 вида, 3 неделя = 3 вида, 4 неделя = еще 3 вида.

Для участка B совокупное количество видов будет: 1 неделя = 0 видов, 2 неделя = 1 вид, 3 неделя = 1 вид, 4 неделя = 1 вид и т. Д.

Любой совет будет очень признателен. заранее ура!


person Eddie T    schedule 14.03.2017    source источник
comment
Разве 4-я неделя на площадке B не = 2 видам животных, собакам и кроликам?   -  person r2evans    schedule 14.03.2017


Ответы (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
person r2evans    schedule 14.03.2017
comment
Спасибо @ r2evans за очень четкий ответ. Да, оба ваших предположения верны, и все имеет смысл. Однако, применив этот подход к моему полному набору данных, я столкнулся с проблемой. Наблюдения за животными в реальном исследовании часто оказываются более одного за период наблюдения (в данном случае недели, но мои данные также могут быть организованы в месяцев и дней). Это создает проблему на этапе full_join подхода к expand.grid. который возвращает ошибку: повторяющиеся идентификаторы для строк (1, 2, 3, 4, 5), ... Есть идеи, как это обойти? - person Eddie T; 15.03.2017
comment
Можете ли вы обновить данные образца, чтобы отразить один такой случай? - person r2evans; 15.03.2017
comment
Конечно, @ r2evans, вот обновление дополнительных наблюдений за собаками на 2-й неделе на участке A и дополнительных наблюдений за кроликами на 3-й неделе на участке B. field_site ‹-c (rep (A, 5), rep (B, 6), rep (C, 4)) неделя ‹-c (1,2,2,2,3,2,3,3,3,4,4,1,2,3,4) животное‹ -c (собака, собака , dog, cat, rabbit, dog, dog, rabb‌ it, rabbit, dog, ‌ rabbit, cat, cat, ‌ rabbit, dog) df ‹-as.data.frame (cbind (field_site, week, animal) , head = TRUE) ## Это вызывает ту же ошибку - - person Eddie T; 15.03.2017
comment
Попробуйте добавить distinct() в начале конвейера. - person r2evans; 15.03.2017
comment
Вы получили ответ на свой вопрос? Если да, примите ответ. - person r2evans; 02.04.2017
comment
Привет всем, да, предложение сработало, и большое спасибо @ r2evans за вашу помощь. В этом примере отдельный () должен идти после поля group_ by, а для моих реальных данных мне также пришлось отфильтровать NA (я не могу вставить весь код, так как у меня недостаточно места). tbl_df (df)% ›% filter (animal! = NA)%›% mutate (fake = TRUE)% ›% group_by (field_site, week, animal, fake)%›% independent ()% ›% - person Eddie T; 03.04.2017