2016-05-06 15 views
1

Ich versuche relative Häufigkeiten basierend auf Zeilenbeschriftungen oder Namen zu berechnen (relative Häufigkeit für jeden Test in df$path1 erhalten. So möchte ich die relative Häufigkeit der Zählungen von test1 berechnen und relativ berechnen . Fülle von Zählungen von test2 separat die Summe der relativen Häufigkeit Zahlen von test1 wäre gleich 1.Berechnen der relativen Häufigkeit nach Zeilenbezeichnungen in R? (Vegan-Paket?)

ich zur Zeit des vegan Paket mit, aber offen für andere Optionen

Test-Daten-Set.

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 

Ideal Ausgang für die relative Häufigkeit basierend auf df$path1, würde dies wie folgt aussehen:

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

Antwort

1

Dies ist eine klassische Split-apply-kombinieren Frage. Die buchstäblichsten Weise in Basis R ist

  • die data.frame durch Gruppe gespalten mit split,
  • eine Funktion mit *apply anzuwenden und
  • kombiniert mit do.call(rbind, ...) oder unlist.

so

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 

, die wir zu einer neuen Variablen zuweisen. Allerdings hat eine Basis schön, wenn seltsam benannte Funktion namens ave, die eine Funktion in Gruppen für uns anwenden kann:

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

, die ein gutes Geschäft prägnanter ist, und kann ebenfalls zu einer neuen Variablen zugewiesen werden.

Soll das Hadleyverse, dplyr ‚s Gruppierung kann der Prozess besser lesbar machen:

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 

Wie Sie sehen können, ist es eine neue Version des data.frame zurückgibt, die wir überschreiben verwenden können, um das vorhandene oder eine neue Kopie erstellen.

Welchen Weg Sie auch wählen, machen Sie sich mit der Logik vertraut, denn Sie werden wahrscheinlich viel davon verwenden. Besser, lerne alle von ihnen. Und tapply und mapply/Map. Und data.table ... warum nicht?


Hinweis: Sie können auch das value/sum(value)) Konstrukt mit der prop.table Funktion ersetzen, wenn Sie möchten. Es ist prägnanter (z. B. ave(df$value, df$path1, FUN = prop.table)), aber weniger offensichtlich, was es macht, weshalb ich es hier nicht verwendet habe.