在唯一对(列)之间共享变量,在R中给出widyr()错误

在唯一对(列)之间共享变量,在R中给出widyr()错误,r,R,我试图计算区域对之间共有多少物种。因此,如果物种A、B和C都出现在,比如说,美国和加拿大,但物种D只出现在加拿大,那么美加对的共享物种数量=3。我在R中使用widyr()包在一个大型数据集(50个国家超过10000种)上实现了这一点,但我得到了两个错误: 如果我分析整个数据集,一些区域对会丢失,而如果我只是将这两个区域子集,那么它就会工作(给出该区域对的共享物种数)。 2)我只尝试了区域的一个子集,与使用完整的数据集相比,我得到了关于共有多少物种的不同答案 我看过一些关于计算对之间的距离和唯一对

我试图计算区域对之间共有多少物种。因此,如果物种A、B和C都出现在,比如说,美国和加拿大,但物种D只出现在加拿大,那么美加对的共享物种数量=3。我在R中使用widyr()包在一个大型数据集(50个国家超过10000种)上实现了这一点,但我得到了两个错误:

  • 如果我分析整个数据集,一些区域对会丢失,而如果我只是将这两个区域子集,那么它就会工作(给出该区域对的共享物种数)。 2)我只尝试了区域的一个子集,与使用完整的数据集相比,我得到了关于共有多少物种的不同答案
  • 我看过一些关于计算对之间的距离和唯一对的类似帖子,但这并不是我想要做的。我以前从未使用过widyr,我不知道错误是什么-我想知道它是否是“第一个”和“最后一个”的东西

    #下面是sample.dat.sub dput-它很长,但我不确定我是否能用几行重现这个问题
    #sample.dat.sub有cols“物种id”和“rgn\u id”
    ##获取col名称
    spp_id%不同(物种id)%%>%as.character()
    rgn\u id%不同(rgn\u id)
    rgn_ID%
    #也许这就是问题所在?
    突变(rgn1=第一个(rgn_id),rgn2=最后一个(rgn_id))
    结果0.df%
    分组依据(rgn1,rgn2)%>%
    #每个区域对共享的唯一物种数
    总结(n_spp=n_独特(物种id))
    #问题是:
    result.df%>%filter(rgn1==134)#说134-136有27种共有物种,但如果我只分析这2种灵长类动物,它说它们共有75种。。。
    ##测试样本
    sample.test%过滤器(rgn_id%在%c中(134136))
    #获取col名称
    test.spp_id%不同(物种_id)%%>%as.character()
    test.rgn\u id%不同(rgn\u id)
    test.rgn_id%
    突变(rgn1=第一个(rgn_id),rgn2=最后一个(rgn_id))
    test.pairs.df
    test.result.df%
    分组依据(rgn1,rgn2)%>%
    总结(n_spp=n_独特(物种id))
    test.result.df%>%arrange(desc(n_spp))35;现在它说共有75个物种
    ##样本数据
    
    sample.dat.sub从未使用过
    widyr
    。您可以尝试以下方法:

    library(dplyr)
    library(purrr)
    
    df_res <- df %>% 
      group_by(rgn_id) %>% 
      summarise(species = list(unique(species_id)))
    
    expand.grid(df_res$rgn_id, df_res$rgn_id) %>% 
      filter(as.integer(Var1) < as.integer(Var2)) %>% 
      mutate(
        n = map2(
          Var1, Var2, 
          ~length(
            intersect(
              filter(df_res, rgn_id == .x) %>% pluck("species", 1), 
              filter(df_res, rgn_id == .y) %>% pluck("species", 1)
            )
          )
        )
      )
    
    库(dplyr)
    图书馆(purrr)
    df_res%
    分组依据(rgn\U id)%>%
    总结(物种=列表(唯一(物种id)))
    展开.grid(df_res$rgn_id,df_res$rgn_id)%>%
    筛选器(as.integer(Var1)%
    变异(
    n=map2(
    Var1,Var2,
    ~length(
    相交(
    过滤器(df_res,rgn_id==.x)%>%采摘(“种类”,1),
    过滤器(df_res,rgn_id==.y)%>%采摘(“种类”,1)
    )
    )
    )
    )
    
    以下代码应该可以解答您的问题。在
    tidyverse
    中使用自连接解决问题非常简单,不需要额外的包
    widyr
    (我不知道)

    library(dplyr)#注意:如果您想要完整的功能,请使用library(tidyverse)
    df_distinct%distinct(物种id、rgn_id)
    内部联接(df_distinct,df_distinct,by=“species_id”,后缀=c(“_1”,“_2”))%>%
    过滤器(rgn\U id\U 1%
    总结(nb_普通_物种=n()
    
    哇,这是非常简单和直接的,谢谢@Pierre Grame!我不知道dplyr中的自连接,非常有用。这也很有效,我发现自连接选项更容易,但了解expand.grid很好-我以前没有使用过它。请记住,在列上连接(不是键)会导致笛卡尔积。这样做,结果表可能有太多的行(如果起始表足够大)。嗯,好的,我不确定这意味着什么。你是说自连接会造成内存分配问题吗?
    library(dplyr)
    library(purrr)
    
    df_res <- df %>% 
      group_by(rgn_id) %>% 
      summarise(species = list(unique(species_id)))
    
    expand.grid(df_res$rgn_id, df_res$rgn_id) %>% 
      filter(as.integer(Var1) < as.integer(Var2)) %>% 
      mutate(
        n = map2(
          Var1, Var2, 
          ~length(
            intersect(
              filter(df_res, rgn_id == .x) %>% pluck("species", 1), 
              filter(df_res, rgn_id == .y) %>% pluck("species", 1)
            )
          )
        )
      )
    
    library(dplyr)  #NB: use library(tidyverse) if you want full functionality
    
    df_distinct <- sample.dat.sub %>% distinct(species_id, rgn_id)
    
    inner_join(df_distinct, df_distinct , by="species_id", suffix=c("_1","_2")) %>% 
      filter(rgn_id_1 < rgn_id_2) %>% 
      group_by(rgn_id_1, rgn_id_2) %>% 
      summarise(nb_common_species = n())