Описание описания R tapply

Я понимаю, что делает tapply() в R. Однако я не могу разобрать это описание из документа:

Apply a Function Over a "Ragged" Array

Description:

     Apply a function to each cell of a ragged array, that is to each
     (non-empty) group of values given by a unique combination of the
     levels of certain factors.

Usage:

     tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)

Когда я думаю о tapply, я думаю о группе в sql. Вы группируете значения в X вместе по своим параллельным уровням факторов в INDEX и применяете FUN к этим группам. Я прочитал описание tapply 100 раз и до сих пор не могу понять, как то, что он говорит, сопоставляется с тем, как я понимаю tapply. Может быть, кто-то может помочь мне разобрать его?

Ответ 1

Посмотрим, что говорит документация R на тему:

Комбинация вектора и фактор маркировки является примером того, что иногда называют оборванным массивом, поскольку размеры подкласса, возможно, нерегулярны. Когда размеры подкласса одинаковы, индексация может выполняться неявно и намного эффективнее, как мы видим в следующем разделе.

Список факторов, которые вы поставляете через INDEX вместе, определяет набор подмножеств X, возможно, разных длин (следовательно, "оборванный" дескриптор). И затем к каждому подмножеству применяется FUN.

EDIT: @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 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))

Ответ 2

@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")

So tapply с этими двумя векторами, поскольку первые параметры действительно позволяют нам применять эту функцию к каждой "строке" нашего оборванного массива.