【问题标题】:Working with the output of tapply() vs. ddply {plyr} in R: subsets of unequal length在 R 中使用 tapply() 与 ddply {plyr} 的输出:长度不等的子集
【发布时间】:2011-11-02 18:04:54
【问题描述】:

我有一个数据框:

> 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

这给了我我想要的,但是输出的格式很时髦,我不知道如何对结果进行额外的分析。

我尝试过使用 plyr 中的 ddply(),类似于:

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

但我显然不正确,而且我什至不确定 ddply() 是否适合我的问题,因为我对每个物种有不同数量的长度观察。

我是否应该更仔细地研究 plyr 中的其他选项?或者有没有办法写一个 for 循环来做我需要的?

【问题讨论】:

  • 我不确定您的问题究竟是什么,但我怀疑您的第一步应该是决定确切您希望输出包含什么。使用您想要的信息绘制包含列名称和值的数据框。这可能会给您(和我们)一些关于该做什么的线索。
  • @gkcn:这些数据是从哪里来的?你是 OP 吗?
  • @ThiefMaster 这是原帖的数据,我刚刚打印出来看看到底是什么。

标签: r subset plyr


【解决方案1】:

你在正确的轨道上! 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

【讨论】:

  • 谢谢约翰!这很好用,并且提供了很好的干净输出。它还为我连接了一些点,就如何设置函数来运行 ddply...:)
  • @Christy 完美!我很高兴它有所帮助。
【解决方案2】:

您可以通过使用plyr 中的count 函数以更简单的方式完成此操作

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

【讨论】:

    猜你喜欢
    • 2012-08-18
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 2015-05-12
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多