【问题标题】:Convert species regional occurence to presense/absence matrix将物种区域出现转换为存在/不存在矩阵
【发布时间】:2019-05-14 23:13:10
【问题描述】:

我有一个数据框,其中第一列是物种名称,第二列是物种生活的地方,按区域编码。我想将此数据框转换为存在/不存在矩阵,其中行是物种名称,列是区域,每个记录(在标题之后)是一系列 0(表示给定区域中不存在)和 1(表示存在于给定区域)。

示例输入:

    species     regions
    species1    area1
    species2    area2,area3
    species3    area2,area3

期望的输出:

   species  area1   area2   area3
   species1     1       0       0 
   species2     0       1       1
   species3     0       1       1

有人对如何在 R 中进行这种转换有任何建议吗?

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    dplyr/tidyr 的方法是首先将 species 分成不同的行,group_by species 并为每个组创建一个行标识符,然后将 spread 它转换为宽格式,因为我们只需要在场缺席信息 (1/0) 我们可以将任何大于 1 的数字更改为 1。

    library(dplyr)
    library(tidyr)
    
    df %>%
      separate_rows(regions, sep = ",") %>%
      group_by(species) %>%
      mutate(row= row_number()) %>%
      spread(regions, row, fill = 0) %>%
      mutate_at(vars(starts_with("area")), ~replace(., . > 1, 1))
    
    #  species  area1 area2 area3
    #  <fct>    <dbl> <dbl> <dbl>
    #1 species1     1     0     0
    #2 species2     0     1     1
    #3 species3     0     1     1
    

    【讨论】:

    • 在我的示例中,我使用了 area1、area2、area3。如果区域名称没有模式怎么办?例如南、CAN、CDH
    • @user11501147 唯一的问题可能出现在mutate_at 的最后一步,在这种情况下,您可以使用列号,然后像mutate_at(2:4, ~replace(., . &gt; 1, 1))
    【解决方案2】:

    我们可以使用base R 轻松做到这一点,方法是用, 拆分'regions' 列,使用'species' 设置list 元素的名称,将list 转换为两列data.frame使用stack 并使用table 获取频率

    table(stack(setNames(strsplit(df1$regions, ","), df1$species)))
    #     ind
    #values  species1 species2 species3
    #  area1        1        0        0
    #  area2        0        1        1
    #  area3        0        1        1
    

    或者更简洁的mtabulate

    library(qdapTools)
    cbind(df1[1], mtabulate(strsplit(df1$regions, ",")))
    #    species area1 area2 area3
    #1 species1     1     0     0
    #2 species2     0     1     1
    #3 species3     0     1     1
    

    数据

    df1 <- structure(list(species = c("species1", "species2", "species3"
    ), regions = c("area1", "area2,area3", "area2,area3")), 
    class = "data.frame", row.names = c(NA, 
     -3L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 2013-10-17
      • 2018-08-06
      • 1970-01-01
      • 2014-04-29
      • 2019-09-08
      • 1970-01-01
      相关资源
      最近更新 更多