解释 R 中的 tapply 函数描述

22
我明白在R语言中tapply()的作用,但我无法理解文档中对它的描述:
对“不规则”数组应用函数
描述:
对不规则数组(也就是被某些因子唯一组合的水平所确定的每个(非空)值组)中的每一个单元格应用函数。
用法:
tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)
当我想到tapply时,我会把它和sql中的group by联系起来。你可以通过INDEX中的平行因子级别将X中的值分组,并将FUN应用于这些组。我已经读了tapply的描述100遍仍然无法理解如何将其与我理解的tapply相对应。或许有人能帮我搞清楚吗?

好问题。我也被同样的事情困扰了。 - Andrie
1
谢谢您用“group by”做比喻,这对我很有帮助。 - Mars
2个回答

20

@joran的出色回答帮助我理解了它(所以请投票赞成他-如果评论太长,我会将其添加为评论),但这可能对某些人有所帮助:

在许多编程语言中,您都可以使用二维数组。根据语言不同,这些数组具有固定的维度(即每行具有相同数量的列),或者有些语言允许每行的项数不同。因此,不是:

A: 1  2  3
B: 4  5  6
C: 7  8  9

你可以得到类似这样的东西

A: 1  3
B: 4  5  6
C: 8

这被称为不规则数组,因为右边看起来很不整齐。按照典型的R风格,我们可能会将其表示为两个向量:

values<-c(1,3,4,5,6,8)
names<-c("A", "A", "B", "B", "B", "C")
所以,使用这两个向量作为第一个参数的确实允许我们将此函数应用于我们不规则数组的每一“行”。

2
+1 很好。我认为让人们困惑的是(包括我第一次阅读tapply文档时),我立即想到如果我有一个“不整齐”的形式,为什么不只是将其存储在list(A=c(1,3),B=c(4,5,6),C=8)中并使用lapply呢?对我来说关键是意识到当您以“长”形式组织数据时,例如通过cbind-ing valuesnames时,它非常有用。 - joran
3
如果你使用split(values, names),你会得到一个不规则的数组。如果你查看tapply的源代码,你会发现它正是这样做的,然后对所得到的列表使用sapply函数。 - Joris Meys
1
@Joris - 是的;我认为大部分混淆都来自文档措辞。一旦你查看源代码,就会很清楚发生了什么。但第一次阅读时,我肯定是被留下了困惑,不知道他们所说的“不规则数组”是什么意思。 - joran

19

让我们看看R文档对此的解释:

向量和标签因子的组合是所谓的不规则数组(即“ragged array”)的一个例子,因为子类大小可能是不规则的。当子类大小都相同时,可以隐式地进行索引,这样更有效率,下一节中将看到。

你通过INDEX提供的因子列表一起指定了X的一组子集,它们的长度可能不同(因此被称为“ragged”)。然后将FUN应用于每个子集。

编辑:@Joris在评论中提出了一个很好的观点。可以将tapply(X,Y,...)视为sapply(split(X,Y),...)的包装器,如果Y是分组因子的列表,则基于它们唯一的水平构建一个新的单一分组因子,相应地分割X并将FUN应用于每个部分。

编辑:以下是一个说明性的例子:

library(lattice)
library(plyr)
set.seed(123)

#Make this example unbalanced
dat <- barley[sample(1:120,50),]

#Suppose we want the avg yield by year/site:
table(dat$year,dat$site)

#That's what they mean by 'ragged' array; there are different
# numbers of obs at each comb of levels

#In plyr we could use ddply:
ddply(dat,.(year,site),.fun=function(x){mean(x$yield)})

#Which gives the same result (listed in a diff order) as:
melt(tapply (dat$yield, list (dat$year, dat$site), mean))

6
值得一提的是,tapply(X,Y,...) 本质上只是 sapply(split(X,Y),...) 的包装器,这很清楚地说明了不规则数组的情况。 - Joris Meys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接