1) apply / tapply Для каждой строки используйте tapply, используя ИНДЕКС префиксов имени и функцию mean
. Транспонировать результат. Пакеты не используются.
prefix <- sub("\\..*", "", names(df))
t(apply(df, 1, tapply, prefix, mean))
с этой матрицей (оберните ее в data.frame (...), если вам нужен результат фрейма данных):
CB_1 HC_1 HC_2
[1,] 0.5 1.5 3
[2,] 5.0 1.5 3
[3,] 4.5 2.0 4
[4,] 4.0 5.0 5
2) lm Запустите указанную регрессию. +0 в формуле означает, что не добавляет перехват. Транспонирование коэффициентов будет требуемой матрицей m
. В следующей строке сделайте имена лучше. prefix
из (1). Пакеты не используются.
m <- t(coef(lm(t(df) ~ prefix + 0)))
colnames(m) <- sub("prefix", "", colnames(m))
m
с этой матрицей
CB_1 HC_1 HC_2
[1,] 0.5 1.5 3
[2,] 5.0 1.5 3
[3,] 4.5 2.0 4
[4,] 4.0 5.0 5
Это следует из того факта, что (1) матрица модели X содержит только единицы и нули и (2) отдельные столбцы из этого ортогональны. Здесь показана матрица модели:
X <- model.matrix(~ prefix + 0) # model matrix
X
, что дает:
prefixCB_1 prefixHC_1 prefixHC_2
1 1 0 0
2 1 0 0
3 0 0 1
4 0 1 0
5 0 1 0
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$prefix
[1] "contr.treatment"
Поскольку столбцы матрицы модели X
ортогональны коэффициенту, соответствующему любому столбцу для конкретной строки, y, из df
(столбец t(df)
) просто sum(x * y) / sum(x * x)
, а поскольку x
- это вектор 0/1, который равен среднему значению значений y
, соответствующих единицам в x
.
3) stack / tapply Преобразовать в длинную форму, вставив столбец id
одновременно. Затем используйте tapply
, чтобы преобразовать обратно в широкоформатную форму mean
. Пакеты не используются.
long <- transform(stack(df), ind = sub("\\..*", "", ind), id = c(row(df)))
with(long, tapply(values, long[c("id", "ind")], mean))
с указанием этой таблицы. Оберните его в as.data.frame.matrix
, если вы хотите data.frame.
ind
id CB_1 HC_1 HC_2
1 0.5 1.5 3
2 5.0 1.5 3
3 4.5 2.0 4
4 4.0 5.0 5