Объясните описание
Я понимаю, что делает tapply() в R. Однако я не могу разобрать это описание из документации:
Примените функцию над "рваным" массивом Описание: Примените функцию к каждой ячейке рваного массива, то есть к каждому (не пустая) группа значений, заданная уникальной комбинацией уровни определенных факторов. Использование: tapply(X, INDEX, FUN = NULL, ..., упрощение = TRUE)
Когда я думаю о tapply, я думаю о group by в sql. Вы группируете значения в X вместе по уровням параллельных факторов в INDEX и применяете FUN к этим группам. Я прочитал описание tapply 100 раз и до сих пор не могу понять, как то, что он говорит, соответствует тому, как я понимаю tapply. Возможно, кто-то может помочь мне разобрать это?
2 ответа
Давайте посмотрим, что R документация говорит по этому вопросу:
Комбинация вектора и фактора маркировки является примером того, что иногда называют рваным массивом, поскольку размеры подкласса, возможно, нерегулярны. Когда размеры подкласса одинаковы, индексация может выполняться неявно и намного более эффективно, как мы увидим в следующем разделе.
Список факторов, которые вы предоставляете через INDEX
вместе указать коллекцию подмножеств X
возможно различной длины (отсюда и "рваный" дескриптор). А потом 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))
Отличный ответ @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")
Так tapply
с этими двумя векторами в качестве первых параметров действительно позволяет нам применять эту функцию к каждой "строке" нашего рваного массива.