Объясните описание

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

Другие вопросы по тегам