通过R中的行标签计算相对丰度?(纯素食套餐?)



我试图根据行标签或名称计算相对丰度(在df$path1中获得每个测试的相对丰度。所以我想从test1计算计数的相对丰度,并分别从test2计算计数的相关丰度。test1的相关丰度数之和等于1。

我目前正在使用vegan软件包,但对其他选项持开放态度。

测试数据集:

library(vegan)
df <- data.frame(x = c("a", "b", "c", "d", "e"), 
                 path1 = c("test1", "test1", "test2", "test2", "test3"),
                 value = c(40, 10, 34, 12, 20))
df$relabun <- decostand(df[3], 2, method = "total") #takes relative abundace of whole column

基于df$path1的相对丰度的理想输出如下:

x path1 relabun_bypath1
a test1 0.8
b test1 0.2
c test2 0.74
d test2 0.26
e test3 1

这是一个经典的拆分-应用-组合问题。基本R中最字面的方式是

  • 用CCD_ 7分组分割数据帧
  • 使用*apply应用函数,以及
  • 与CCD_ 9或CCD_

所以

unlist(lapply(split(df, df$path1), function(x){x$value / sum(x$value)}))
#    test11    test12    test21    test22     test3 
# 0.8000000 0.2000000 0.7391304 0.2608696 1.0000000 

我们可以将其分配给一个新的变量。然而,base有一个很好的函数ave,它可以为我们跨组应用一个函数:

ave(df$value, df$path1, FUN = function(x){x / sum(x)})
# [1] 0.8000000 0.2000000 0.7391304 0.2608696 1.0000000

它要简洁得多,并且同样可以分配给一个新的变量。

如果你更喜欢Hadleyverse,dplyr的分组可以使过程更可读:

library(dplyr)
df %>% group_by(path1) %>% mutate(relAbundByPath = value / sum(value))
# Source: local data frame [5 x 4]
# Groups: path1 [3]
# 
#        x  path1 value relAbundByPath
#   (fctr) (fctr) (dbl)          (dbl)
# 1      a  test1    40      0.8000000
# 2      b  test1    10      0.2000000
# 3      c  test2    34      0.7391304
# 4      d  test2    12      0.2608696
# 5      e  test3    20      1.0000000

正如您所看到的,它返回data.frame的新版本,我们可以使用它来覆盖现有版本或制作新的副本。

无论你选择哪种路线,都要熟悉逻辑,因为你可能会经常使用它。更好的是,学习所有这些。以及CCD_ 13和CCD_ 14/CCD_。和data.table。。。为什么不呢?


注意:如果您愿意,还可以用prop.table函数替换value / sum(value))构造。它更简洁(例如ave(df$value, df$path1, FUN = prop.table)),但它的作用不那么明显,这就是为什么我没有在这里使用它。

最新更新