разделить data.frame по столбцам, используя переменную группировки - PullRequest
10 голосов
/ 26 апреля 2011

Довольно просто разбить data.frame на строки в зависимости от коэффициента группировки. Но как мне разбить на столбцы и, возможно, применить функцию?

my.df <- data.frame(a = runif(10),
        b = runif(10),
        c = runif(10),
        d = runif(10))
grp <- as.factor(c(1,1, 2,2))

То, что я хотел бы иметь, - это среднее значение по группам.

То, что я имею до сих пор, - это заявление бедного человека.

lapply(as.list(as.numeric(levels(grp))), FUN = function(x, cn, data) {
            rowMeans(data[grp %in% x])
        }, cn = grp, data = my.df)

EDIT Спасибо всем за участие. Я выполнил 10 копий *, и мой рабочий data.frame имеет примерно 22000 строк. Это результаты в секундах.

Roman: 2.19
Joris: 4.60
Joris #2: 3.79 #changed sapply to lapply as suggested by Joris in the [R chatroom][1].
Gavin: 4.70
James & EDi: > 200 # * ran only one replicate due to the large order of magnitude difference

Мне показалось странным, что для этой задачи нет функции-обертки. Может быть, когда-нибудь мы сможем сделать

apply(X = my.df, MARGIN = 3, INDEX = my.groups, FUN = mean) # :)

Ответы [ 4 ]

6 голосов
/ 26 апреля 2011

Вы можете использовать ту же логику, но в более удобной форме:

sapply(levels(grp),function(x)rowMeans(my.df[which(grp==x)]))
5 голосов
/ 26 апреля 2011

Преобразуйте my.df в список и разбейте его, затем примените свою функцию к каждому подмножеству компонентов списка после приведения к фрейму данных:

lapply(split(as.list(my.df), grp), function(x) rowMeans(as.data.frame(x)))

Это дает:

> lapply(split(as.list(my.df), grp), function(x) rowMeans(as.data.frame(x)))
$`1`
 [1] 0.8229189 0.4901288 0.2057578 0.6531641 0.3897858 0.4225179
 [7] 0.3905410 0.3928784 0.1715857 0.3973192

$`2`
 [1] 0.61348623 0.61229702 0.31938521 0.28325342 0.25857158
 [6] 0.49071991 0.01179999 0.57639186 0.38407240 0.17467337

Что эквивалентно "роману @ Романа":

> roman <- lapply(as.list(as.numeric(levels(grp))), 
+                 FUN = function(x, cn, data) {
+                     rowMeans(data[grp %in% x])
+                 }, cn = grp, data = my.df)
> gavin <- lapply(split(as.list(my.df), grp), 
+                 function(x) rowMeans(as.data.frame(x)))
> all.equal(roman, gavin)
[1] "names for current but not for target"

за исключением названий компонентов.

0 голосов
/ 26 апреля 2011

Как насчет:

my.df2 <- data.frame(t(my.df),grp)
aggregate(.~grp,my.df2,mean)
0 голосов
/ 26 апреля 2011

Это работает?

aggregate(t(my.df), list(grp), mean)
...