将带有物种的 tibble 按站点数据转换为 vegan::diversity() 的数字矩阵

Convert tibble with species by site data into numeric matrix for vegan::diversity()

我有 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 级别。由于我最初的尝试失败了,我决定将上述数据分成两部分,按 CU 两个级别,然后删除 Layer 列并转换 Pointrownames.

结果,我得到的数据理论上只是数字(所有剩余的列都有相应物种的计数)。但实际上,情况似乎并非如此,这就是我的问题所在。然后我使用 as.matrix 转换了 data.frame 但我仍然收到以下错误: 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])

但这会丢失行号,因此会丢失点标识。尽管 diversity() 现在可以工作,但它会将所有值视为一个,并且只为整个数据计算一个多样性指数(而不是在我的原始数据格式中为每一行计算一个值)。

  1. 为什么 diversity() 不能处理这些数据?我该怎么做才能解决这个问题?
  2. 有什么方法可以执行 diversity() 而不必将具有两个 Layer 级别的原始数据拆分为两个单独的矩阵?

在我看来,您的原始数据框将数字列存储为 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")

恐怕我对多样性还不够熟悉,无法回答你的第二个问题。