Преобразуйте таблицу с данными о видах по участкам в числовую матрицу для vegan ::iversity ()

У меня есть данные в формате tibble, который выглядит следующим образом (с еще 22 строками и еще 7 столбцами):

reprex[1:10,1:7]
# A tibble: 10 x 7
# Groups:   Point, Layer [10]
   Point Layer Lari_deci Quer_rope Pinu_sylv Betu_pend Sorb_aucu
   <chr> <chr> <chr>     <chr>     <chr>     <chr>     <chr>    
 1 P03   C     21        17        5         1         0        
 2 P03   U     0         0         0         0         3        
 3 P06   C     3         28        28        0         0        
 4 P07   C     0         3         20        1         1        
 5 P07   U     0         0         0         0         0        
 6 P08   C     0         16        21        0         0        
 7 P08   U     0         0         0         0         0        
 8 P10   C     0         17        44        1         0        
 9 P10   U     0         50        0         0         0        
10 P11   C     0         36        1         0         0  
> dput(reprex[1:10,1:7])
structure(list(Point = c("P03", "P03", "P06", "P07", "P07", "P08", 
"P08", "P10", "P10", "P11"), Layer = c("C", "U", "C", "C", "U", 
"C", "U", "C", "U", "C"), Lari_deci = c("21", "0", "3", "0", 
"0", "0", "0", "0", "0", "0"), Quer_rope = c("17", "0", "28", 
"3", "0", "16", "0", "17", "50", "36"), Pinu_sylv = c("5", "0", 
"28", "20", "0", "21", "0", "44", "0", "1"), Betu_pend = c("1", 
"0", "0", "1", "0", "0", "0", "1", "0", "0"), Sorb_aucu = c("0", 
"3", "0", "1", "0", "0", "0", "0", "0", "0")), row.names = c(NA, 
-10L), groups = structure(list(Point = c("P03", "P03", "P06", 
"P07", "P07", "P08", "P08", "P10", "P10", "P11"), Layer = c("C", 
"U", "C", "C", "U", "C", "U", "C", "U", "C"), .rows = structure(list(
    1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), ptype = integer(0), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))), row.names = c(NA, 10L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

Я хочу рассчитать индекс разнообразия Симпсона для каждого Point, учитывая два Layer уровня по отдельности. Поскольку мои первоначальные попытки сделать это не удались, я решил разделить приведенные выше данные на два, по двум уровням C и U, а затем удалить столбец Layer и преобразовать Point в rownames.

В результате я получил данные, которые теоретически были только числовыми (во всех остальных столбцах были подсчеты соответствующих видов). Но на практике это не так, и в этом моя проблема. Затем я преобразовал data.frame с помощью as.matrix, но все равно получаю следующую ошибку: Error in diversity(., index = "simpson") : input data must be numeric

reprex_C <- reprex %>% filter(Layer == "C") %>% ungroup %>% select(-2) %>% 
  column_to_rownames(var="Point") %>% as.matrix %>% 
  diversity(index = "simpson")
# I would have a similar 'reprex_U' object for Layer == "U".

Я попытался найти способы исправить это, каким-то образом преобразовав значения столбцов из символьных в числовые:

as.numeric(reprex_C[,1:14])

но при этом теряются номера строк и, следовательно, идентичность Point. И хотя diversity() теперь работает, он рассматривает все значения как одно и вычисляет только один индекс разнообразия для всех данных (в отличие от одного значения для каждой строки в моем исходном формате данных).

  1. Почему diversity() не работает с такими данными? Что я могу сделать?
  2. Есть ли способ выполнить diversity() без разделения исходных данных с двумя Layer уровнями на две отдельные матрицы?

person Karthik Thrikkadeeri    schedule 02.11.2020    source источник


Ответы (1)


Мне кажется, что ваш исходный фрейм данных имеет числовые столбцы, хранящиеся как chr. Если вы приведете их к числовым значениям до того, как сделаете разбиение, все должно работать нормально:

reprex_C <- reprex %>% 
  mutate(across(Lari_deci:Sorb_aucu,.fns = as.numeric)) %>%
  filter(Layer == "C") %>% ungroup %>% select(-2) %>% 
  column_to_rownames(var="Point") %>% as.matrix %>%
  vegan::diversity(index = "simpson")

Боюсь, я недостаточно знаком с разнообразием, чтобы ответить на ваш второй вопрос.

person SirTain    schedule 02.11.2020
comment
Я попробовал то, что вы предложили, но получаю ту же ошибку, что и раньше: Error in diversity(., index = "simpson") : input data must be numeric - person Karthik Thrikkadeeri; 02.11.2020
comment
Это странно, потому что у меня это работает. Я вижу, вы упомянули, что есть 7 дополнительных столбцов. Вы изменили код в строке 2, где я поместил Lari_deci:Sorb_aucu, чтобы включить первый и последний числовые столбцы, с которыми вы имеете дело? - person SirTain; 02.11.2020
comment
Ой, элементарно! Извините за это, я пропустил этот шаг, но теперь он работает. Спасибо! - person Karthik Thrikkadeeri; 03.11.2020
comment
веганский должен быть слепым, а тиббл должен работать как настоящие синие фреймы данных (пожалуйста, отправьте отчет об ошибке в github.com/vegandevs/vegan/issues, если это не удается). Настоящая проблема здесь, похоже, в том, что в ваших данных были не числа, а текст. Преимущество tibbles в том, что с tibbles вы получаете информацию о типах переменных, и если вы видите их <chr>, не следует ожидать, что какой-либо числовой метод будет работать. - person Jari Oksanen; 13.11.2020