Описание описания 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
с этими двумя векторами, поскольку первые параметры действительно позволяют нам применять эту функцию к каждой "строке" нашего оборванного массива.