2016-05-06 5 views
1

Я пытаюсь рассчитать относительные количества обитателей, основанные на ярлыках строк или именах (получите относительное обилие для каждого теста в df$path1. Поэтому я хотел бы рассчитать относительное количество отсчетов от test1 и рассчитать относительную численность . обилие графов из test2 отдельно сумма относительных чисел численности от test1 будет равно 1.Рассчитать относительную численность по метке строки в R? (vegan package?)

Я в настоящее время использую 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 

ответ

1

Это классический сплит-применить-скомбинировать вопрос. Самым буквальным образом в базовом R является

  • разделить data.frame группой с split,
  • применить функцию с *apply и
  • в сочетании с do.call(rbind, ...) или unlist.

так

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 

который можно присвоить новой переменной. Тем не менее, база имеет приятный, если ни странно, с именем функция называется 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 «s группирования может сделать процесс более удобным для чтения:

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, которую мы можем использовать для перезаписи существующий или создать новую копию.

Какой бы маршрут вы ни выбрали, подойдите к логике, потому что вы, вероятно, будете ее использовать. Лучше узнайте все. И tapply и mapply/Map. И data.table ... почему бы и нет?


Примечание: Вы также можете заменить value/sum(value)) конструкцию с функцией prop.table, если вам нравится. Это более красноречиво (например, ave(df$value, df$path1, FUN = prop.table)), но менее очевидно, что он делает, поэтому я не использовал его здесь.