我想将潜在分数矩阵转换为观察分数。
可以通过将断点/阈值应用于原始矩阵来实现,从而最终得到一个新的分类矩阵。这样做很简单,例如:
#latent variable matrix
true=matrix(c(1.45,2.45,3.45,
0.45,1.45,2.45,
3.45,4.45,5.45)
,ncol=3,byrow=TRUE)
#breaks for the cut function
br=c(-Inf,1,2,3,4,Inf)
#apply cut function to latent variable
observed=apply(true,c(1,2),cut,breaks=br,labels=FALSE,include.lowest=TRUE)
但是,我需要做的是将不同的中断应用于原始矩阵的每一行。这些阈值存储在矩阵中:
#matrix of breaks for the cut function
br=matrix(c(-Inf,1,2,3,4,Inf,
-Inf,1.5,2.5,3.5,4.5,Inf,
-Inf,2,3,4,5,Inf)
,ncol=6,byrow=TRUE)
也就是说, br 矩阵的第1行应作为 true 矩阵的第1行的中断,仅适用于该行 , br 的第2行是 true 等第2行的中断。
使用以下内容似乎无法完成工作:
for (i in 1:nrow(true)) {
observed[i,]=apply(true[i,],c(1,2),cut,breaks=br[i,],labels=FALSE,include.lowest=TRUE)
}
你有什么想法吗?有没有办法将相应的br线应用于相应的真线并将其保存在观察到的同一线?
非常感谢提前!
KH
答案 0 :(得分:1)
一些函数式编程和Map
可以解决问题:
splitLines = function(m) split(m, rep(1:nrow(m), ncol(m)))
do.call(rbind, Map(cut, splitLines(true), splitLines(br), labels=F, include.lowest=T))
# [,1] [,2] [,3]
#1 2 3 4
#2 1 1 2
#3 3 4 5
答案 1 :(得分:1)
在行数上使用sapply
(基本上只是隐藏for循环)可以提供您想要的内容:
values = sapply(1:nrow(true), function(i)
cut(true[i,], br[i,], labels=FALSE, include.lowest=TRUE)))
values = t(values)
不幸的是,我们需要额外的转置步骤才能使矩阵正确。
关于你问题中的for循环,当你只是对一行进行子集时,即true[i,]
我们只得到一个向量。这会导致apply
中断。要避免使用矢量,您需要一个额外的参数
true[i,, drop=FALSE]