不同级别的因子变量的矩阵计算与来自另一个列表(但具有与矩阵相同的级别)的元素作用于每个级别

时间:2016-06-13 04:15:54

标签: r matrix lapply

我有以下简化问题:

temp <- matrix(rnorm(1200), ncol = 4)
lev <- as.factor(rep(c("a", "b", "c"), each = 100))
dfr <- data.frame(lev = lev, temp = temp)
lv <- lapply(split(dfr, dfr$lev), function(x) var(x[,-1]))

y <- matrix(rnorm(1200), ncol = 4)

让我们说y的行也被赋予与lev相同的级别。因此,对于每个lev,我想矩阵乘以与该级别相关联的方差矩阵的逆。

总结一下,对于对应于级别“a”的所有y行,我想用lv $ a后加倍,对于对应于级别“b”的所有y行,我想使用lv $ b进行后乘,对于对应于级别“c”的所有y行,我想使用lv $ c进行后乘。

在这次转换之后,我想得到一个数据帧或矩阵,其中包含由这些由lev转换的y行给出的行。

2 个答案:

答案 0 :(得分:1)

temp <- matrix(rnorm(1200), ncol = 4)
lev <- as.factor(rep(c("a", "b", "c"), each = 100))
dfr <- data.frame(lev = lev, temp = temp)
lv <- lapply(split(dfr, dfr$lev), function(x) var(x[,-1]))

y <- matrix(rnorm(1200), ncol = 4)


dd <- data.frame(levs = lev, y = y)
levs.mat <- lapply(split(dd, dd$levs), function(x)(x))
tmp <- mapply(FUN = function(x, lev)(as.matrix(x[, -1])%*%solve(lev)), x = levs.mat, lev = lv)

此时,我得到一个尺寸为300 x 4的矩阵,但这三列并不完全正确。我可以将其更改为数组:

dim(tmp) <- c(100, ncol(y), nlevels(lev))
X <- aperm(tmp, c(1, 3, 2))
dim(X) <- dim(y)

检查是否正确:比较

head(X)

y[1:6, ] %*% solve(as.matrix(lv$a))

等,两者都会产生相同的结果。

产生X.

答案 1 :(得分:0)

替代方案:

out <- lapply(split(seq_along(lev), lev),
              function(i) y[i, ] %*% solve(var(temp[i, ])))

现在out是三个100×40矩阵的列表

> lapply(out, dim)
$a
[1] 100   4

$b
[1] 100   4

$c
[1] 100   4

如果需要,可以与do.call(rbind, out)叠加。

注意:请注意,结果与答案中的矩阵X不匹配。我不确定你最后的尺寸变化是什么。