Как получить видовое богатство и численность для участков с несколькими образцами, используя dplyr - PullRequest
0 голосов
/ 28 сентября 2018

Проблема:

У меня есть несколько сайтов, по 10 точек отбора проб на каждом сайте.

Site Time Sample Species1 Species2 Species3 etc
Home    A      1        1        0        4 ...
Home    A      2        0        0        2 ...
Work    A      1        0        1        1 ...
Work    A      2        1        0        1 ...
Home    B      1        1        0        4 ...
Home    B      2        0        0        2 ...
Work    B      1        0        1        1 ...
Work    B      2        1        0        1 ...
...

Я хотел бы получить богатство и изобилие каждого сайта.Богатство - это общее количество видов на сайте, а численность - это общее количество всех особей всех видов на сайте, например:

Site Time Richness Abundance
Home    A        2         7
Work    A        3         4
Home    B        2         7
Work    B        3         4

Я могу добраться туда с двумя функциями (ниже).Тем не менее, я хотел бы, чтобы оба в одной функции dplyr.Диапазон 7:34 относится к моей матрице видов (каждая строка - сайт / образец, виды - как столбцы).

df1 <- df %>% mutate(Abundance = rowSums(.[,4:30])) %>%
group_by(Site,Time) %>%   
    summarise_all(sum)

df1$Richness <- apply(df1[,4:30]>0, 1, sum)

Если я пытаюсь выполнить обе функции в одной функции, я получаю следующую ошибку

df1 <- df  %>% mutate(Abundance = rowSums(.[,4:30]) ) %>%
   group_by(Site, Time) %>%   
   summarise_all(sum) %>% 
   mutate(Richness = apply(.[,4:30]>0, 1, sum))

Error in mutate_impl(.data, dots) : 
  Column `Richness` must be length 5 (the group size) or one, not 19

Часть Richness должна идти после функции суммирования, поскольку она должна работать с суммированными и сгруппированными данными.

Как заставить эту функцию работать?

(ПримечаниеРанее это было помечено как дубликат этого вопроса: Манипулирование отдельными данными о количестве видов в матрице численности вида

Однако это совершенно другой вопрос - этот вопрос, по сути, касается переносанабор данных и суммирование в пределах одного вида / столбца. Речь идет о суммировании всех видов по столбцам (нескольким столбцам). Кроме того, я на самом деле думаю, что ответ на этот вопрос очень полезен - такие экологи, как я, рассчитывают богатство иизобилия все время, и я уверен, что они оценят специальный вопрос.)

1 Ответ

0 голосов
/ 28 сентября 2018

После summarise нам нужно ungroup

library(tidyverse)
df %>% 
  mutate(Abundance = rowSums(.[4:ncol(.)])) %>% 
  group_by(Site, Time) %>% 
  summarise_all(sum) %>%
  ungroup %>% 
  mutate(Richness = apply(.[4:(ncol(.)-1)] > 0, 1, sum)) %>%
  #or
  #mutate(Richness = rowSums(.[4:(ncol(.)-1)] > 0)) %>%
  select(Site, Time, Abundance, Richness)
# A tibble: 4 x 4
#  Site  Time  Abundance Richness
#  <chr> <chr>     <dbl>    <int>
#1 Home  A             7        2
#2 Home  B             7        2
#3 Work  A             4        3
#4 Work  B             4        3

Это также можно записать, выполнив сначала group_by sum, а затем transmute

df %>% 
  group_by(Site, Time) %>%
  summarise_at(vars(matches("Species")), sum)  %>% 
  ungroup %>%
  transmute(Site, Time, Abundance = rowSums(.[3:ncol(.)]), 
                        Richness =  rowSums(.[3:ncol(.)] > 0))

Или другой вариант sum с map

df %>% 
   group_by(Site, Time) %>%
   summarise_at(vars(matches("Species")), sum) %>% 
   group_by(Time, add = TRUE) %>%
   nest %>% 
   mutate(data = map(data, ~ 
                 tibble(Richness = sum(.x > 0), 
                        Abundance = sum(.x)))) %>% 
   unnest

data

df <- structure(list(Site = c("Home", "Home", "Work", "Work", "Home", 
"Home", "Work", "Work"), Time = c("A", "A", "A", "A", "B", "B", 
"B", "B"), Sample = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), Species1 = c(1L, 
0L, 0L, 1L, 1L, 0L, 0L, 1L), Species2 = c(0L, 0L, 1L, 0L, 0L, 
0L, 1L, 0L), Species3 = c(4L, 2L, 1L, 1L, 4L, 2L, 1L, 1L)), 
class = "data.frame", row.names = c(NA, 
 -8L))
...