2011-11-02 91 views
3

的子集我有一個數據幀:與tapply()與ddply {plyr}在R的輸出工作:長度不等

> df <- data.frame(
+ Species = rep(LETTERS[1:4], times=c(5,6,7,6)), 
+ Length = rep(11:14, each=3) 
+) 
> 
> df 

我需要能夠計數在一定的個體數量長度每種物種(即物種A中有多少個體的長度爲1,2,3等)?然後,我需要對輸出執行一系列附加分析。例如,我需要計算每個長度的個體密度,以及從一個長度類別到下一個長度類別的密度的減少。

這很容易,如果我第一子集中的數據:

Spec.A<-df[df$Species=="A",] 

#count number of specimens of each length; 
count<-table(Spec.A$Length) 
count 

#calculate density per length category (divide by total area sampled =30) 
density<-count/(30) 
density 

#calculate the decrease in density (delta.N) from one length category to the next; 
delta.N<-diff(density, lag=1, differences=1) 
delta.N 

的問題是,我需要(通過每個子集,即循環)做這些計算每個物種。一方面,我可以使用tapply()和一個使用table()的函數;另一方面,

#function: count number of specimens of each length; 
count<-function(x){ 
table(x) 
} 

Number<-tapply(df$Length, df$Species, FUN=count, simplify=FALSE) 
Number 

這給了我我想要的,但輸出的格式很時髦,我無法弄清楚如何對結果進行額外的分析。

我一直在使用ddply()從plyr試過了,是這樣的:

ddply(df$Length, df$Species, 
count) 

但我很清楚沒有它的權利,我甚至不能確定ddply()是適合我的問題,因爲我對每個物種的觀測長度都有不同的數目。

我應該更密切地關注plyr中的其他選項嗎?或者有沒有辦法編寫for循環來做我需要的?

+3

這樣做是一個簡單的方法我不知道你到底是什麼問題,但是,這是我做什麼,你的犯罪嫌疑人第一步應該是決定你希望你的輸出包含什麼_exactly_。使用所需信息繪製具有列名稱和值的數據框。這可能會讓你(和我們)知道該怎麼做的一些線索。 – joran

+0

@gkcn:這些數據來自哪裏?你是OP嗎? – ThiefMaster

+0

@ThiefMaster這是來自原始帖子的數據,我剛剛打印出來看看究竟是什麼。 – gkcn

回答

3

您正確的方向!帶有列表輸出的tapply絕對是一種方式,可能是一個不錯的選擇,因爲你的輸出將有不同的長度。

ddply,就像你猜測的那樣,是另一種方式。關鍵是你給ddply的函數的輸出應該是一個數據框架,所有的統計數據都處於「長」模式(這樣它們將很好地堆疊起來)。簡單的count函數不能做到這一點,所以你需要製作自己的函數。我爲這樣的ddply調用設計一個函數的方式實際上與您正在做的非常相似:我得到一部分數據,然後使用它創建我的函數。然後,當你將它提交給ddply時,它將在所有子集中很好地應用該功能。

SpeciesStats <- function(df) { 
    counts = table(df$Length) 
    densities = counts/30 
    delta.N = diff(densities, lag=1, differences=1) 

    data.frame(Length = names(counts), 
      Count = as.numeric(counts), 
      Density = as.numeric(densities), 
      delta.N = c(NA, delta.N), 
      row.names=NULL) 
} 
> ddply(df, 'Species', SpeciesStats) 
    Species Length Count Density  delta.N 
1  A  11  3 0.10000000   NA 
2  A  12  2 0.06666667 -0.03333333 
3  B  12  1 0.03333333   NA 
4  B  13  3 0.10000000 0.06666667 
5  B  14  2 0.06666667 -0.03333333 
6  C  11  3 0.10000000   NA 
7  C  12  3 0.10000000 0.00000000 
8  C  14  1 0.03333333 -0.06666667 
9  D  13  3 0.10000000   NA 
10  D  14  3 0.10000000 0.00000000 
+0

謝謝約翰!這很好,並提供了一個很好的清潔輸出。它也爲我連接了一些點,關於如何設置函數來運行ddply ... :) –

+0

@Christy完美!我很高興它有幫助。 –

3

您可以通過使用count功能plyr

df1 <- ddply(df, .(Species, Length), count) 
df2 <- ddply(df1, .(Species), mutate, Dens = freq/30, Del = diff(c(NA, Dens)))