Многократное применение AVE для средств вычислительной группы в кадре данных
Следующий код отдельно создает групповые средства x
а также y
в соответствии с group
, Предположим, что у меня есть ряд переменных, для которых повторяется одна и та же операция.
Как бы вы предложили действовать, чтобы получить тот же результат с помощью одной команды? (Я полагаю, необходимо принять tapply
, но я не совсем уверен в этом..).
x=seq(1,11,by=2); y=seq(2,12,by=2); group=rep(1:2, each=3)
dat <- data.frame(cbind(group, x, y))
dat$m_x <- ave(dat$x, dat$group)
dat$m_y <- ave(dat$y, dat$group)
dat
Большое спасибо.
3 ответа
Альтернативные решения с использованием data.table
а также plyr
пакеты:
1) Использование data.table
require(data.table)
dt <- data.table(dat, key="group")
# Following @Matthew's comment, edited:
dt[, `:=`(m_x = mean(x), m_y = mean(y)), by=group]
Выход:
group x y m_x m_y
1: 1 1 2 3 4
2: 1 3 4 3 4
3: 1 5 6 3 4
4: 2 7 8 9 10
5: 2 9 10 9 10
6: 2 11 12 9 10
2) используя plyr
и преобразовать:
require(plyr)
ddply(dat, .(group), transform, m_x=mean(x), m_y=mean(y))
выход:
group x y m_x m_y
1 1 1 2 3 4
2 1 3 4 3 4
3 1 5 6 3 4
4 2 7 8 9 10
5 2 9 10 9 10
6 2 11 12 9 10
3) используя plyr
и numcolwise (обратите внимание на уменьшенный вывод):
ddply(dat, .(group), numcolwise(mean))
Выход:
group x y
1 1 3 4
2 2 9 10
Предполагая, что у вас есть более двух столбцов, вы хотели бы использовать apply
применять ave
к каждому столбцу в матрице.
x=seq(1,11,by=2); y=seq(2,12,by=2); group=rep(1:2, each=3)
dat <- cbind(x, y)
ave.dat <- apply(dat, 2, function(column) ave(column, group))
# x y
# [1,] 1 2
# [2,] 3 4
# [3,] 5 6
# [4,] 7 8
# [5,] 9 10
# [6,] 11 12
Вы также можете использовать aggregate():
dat2 <- data.frame(dat, aggregate(dat[,-1], by=list(dat$group), mean)[group, -1])
dat2
group x y x.1 y.1
1 1 1 2 3 4
1.1 1 3 4 3 4
1.2 1 5 6 3 4
2 2 7 8 9 10
2.1 2 9 10 9 10
2.2 2 11 12 9 10
row.names(dat2) <- rownames(dat)
colnames(dat2) <- gsub("(.)\\.1", "m_\\1", colnames(dat2))
dat2
group x y m_x m_y
1 1 1 2 3 4
2 1 3 4 3 4
3 1 5 6 3 4
4 2 7 8 9 10
5 2 9 10 9 10
6 2 11 12 9 10
Если имена переменных больше чем один символ, вам нужно изменить вызов gsub().