【问题标题】:Count values shared between groups计算组之间共享的值
【发布时间】:2015-03-04 00:34:24
【问题描述】:

这是一些虚拟数据:

class<-c("ab","ab","ad","ab","ab","ad","ab","ab","ad","ab","ad","ab","av")
otu<-c("ab","ac","ad","ab","ac","ad","ab","ac","ad","ab","ad","ac","av")
value<-c(0,1,12,13,300,1,2,3,4,0,0,2,4)
type<-c("b","c","d","a","b","c","d","d","d","c","b","a","a")
location<-c("b","c","d","a","b","d","d","d","d","c","b","a","a")
datafr1<-data.frame(class,otu,value,type,location)

如果组“位置”和“类型”中的任何复制为 0,我想删除任何 OTU,因为我对组内所有复制之间共享的 OTU 感兴趣。

我想计算两件事。 一:组“位置”和类型之间共享的所有 OTU 的“价值”百分比丰度(丰度) 二:统计每个类共享的OTU个数(otu.freq)

需要注意的是,我希望 OTU 按“类”分类,而不是 OTU 名称(因为它没有意义)。

预期输出:

   class location type  abundance  otu.freq
    ab        a    a      79        2
    av        a    a      21        1
    ab        b    b     100        1
    ab        c    c     100        1
    ad        d    c     100        1
    ab        d    d      24        2         
    ad        d    d      76        2

我有一个更大的数据框,并使用 dplyr here 尝试了这些建议,但我的 RAM 用完了,所以我不知道它是否有效。

@Akron 下面提供的解决方案不计算丰度为 0 的出现次数,但它不会从该组内的其他复制中删除该 OTU。如果任何 OTU 的丰度为 0,则它不会在该组之间共享,我需要将其从丰度和 otu.freq 计算中完全打折。

library(dplyr)    
so_many_shared3<-datafr1 %>% 
      group_by(class, location, type) %>% 
      summarise(abundance=sum(value)/sum(datafr1[['value']])*100, otu.freq=sum(value !=0))


   class location type  abundance  otu.freq
1    ab        a    a  4.3859649     2
2    ab        b    b 87.7192982     1
3    ab        c    c  0.2923977     1
4    ab        d    d  1.4619883     2
5    ad        b    b  0.0000000     0
6    ad        d    c  0.2923977     1
7    ad        d    d  4.6783626     2
8    av        a    a  1.1695906     1

【问题讨论】:

    标签: r count aggregate shared


    【解决方案1】:

    您可以使用data.table 一步完成此操作

    library(data.table)
    val = sum(datafr1$value)
    setDT(datafr1)[order(class,type), list(abundance = 
                   sum(value)/val*100, otu.freq = .N), 
                   by = .(class, location, type)]
    

    或使用dplyr

    library(dplyr)
    datafr1 %>% 
         group_by(class, location, type) %>% 
         summarise(abundance=sum(value)/sum(datafr1[['value']])*100, otu.freq=n())
     #   class location type  abundance otu.freq
     #1    ab        a    a  4.3859649        2
     #2    ab        b    b 87.7192982        2
     #3    ab        c    c  0.2923977        2
     #4    ab        d    d  1.4619883        2
     #5    ad        b    b  0.0000000        1
     #6    ad        d    c  0.2923977        1
     #7    ad        d    d  4.6783626        2
     #8    av        a    a  1.1695906        1
    

    更新

    根据新标准,我正在更新 OP (@K.Brannen) 建议的代码

      datafr1 %>%
           group_by(class, location, type) %>% 
           summarise(abundance=sum(value)/sum(datafr1[['value']])*100, 
                 otu.freq=sum(value !=0)) 
    

    更新2

    基于更新后的预期结果

      datafr1 %>%
           filter(value!=0) %>% 
           group_by(location, type) %>% 
           mutate(value1=sum(value)) %>% 
           group_by(class, add=TRUE) %>% 
           summarise(abundance=round(100*sum(value)/unique(value1)), 
                             otu.freq=n())
      #    location type class abundance otu.freq
      #1        a    a    ab        79        2
      #2        a    a    av        21        1
      #3        b    b    ab       100        1
      #4        c    c    ab       100        1
      #5        d    c    ad       100        1
      #6        d    d    ab        24        2
      #7        d    d    ad        76        2
    

    【讨论】:

    • 这些都给出了输出,但 dplyr 版本更快。但是,有些类的丰度为 0,并且 otu.freq 不为 0(也显示在您的 dplyr 输出中)。我要统计共享的OTU个数,值为0表示组间不共享OTU。
    • so_many_shared% group_by(Class, location, type) %>% summarise(abundance=sum(value)/sum(so_many_melt[['value']])*100, otu .freq=sum(value !=0)) 这样做吗?我想确保它在做我认为的事情。
    • @K.Brannen 我不在。我会尽快检查您的更新。
    • @K.Brannen 但是您的代码将7th 行otu.freq 提供为2,而不是预期的1。预期中有错别字吗?
    • 好的,所以我发现了其他有问题的东西。如果 OTU 在任何位置和类型的复制中的值为 0,则它不会在所有这些样本之间共享。有什么方法可以去除在任何重复中为 0 的 OTU,并且不计算该 OTU 的丰度或 otu.freq?
    【解决方案2】:

    您的聚合函数有错误。如果要统计 otu 的出现频率,应该把 otu 放在“~”号之前。之后,您可以使用 plyr 库中的 join 函数合并它们

    abund_shared_freq<-aggregate(otu~class+location+type,datafr1,length)
    library(plyr)
    join(abund_shared, abund_shared_freq, by=c("class", "location","type"), type="left")
    

    输出:

      class location type  abundance otu
    1    ab        a    a  4.3859649   2
    2    ab        b    b 87.7192982   2
    3    ab        c    c  0.2923977   2
    4    ab        d    d  1.4619883   2
    5    ad        b    b  0.0000000   1
    6    ad        d    c  0.2923977   1
    7    ad        d    d  4.6783626   2
    8    av        a    a  1.1695906   1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 2015-02-19
      • 1970-01-01
      相关资源
      最近更新 更多