I would like to transform a matrix of latent scores to observed scores.
One can do so by apply break points/thresholds to the original matrix, thus ending up having a new, categorical matrix. Doing so is simple, for example:
#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)
However, what I need to do is apply different breaks to every row of the original matrix. These thresholds are stored in a matrix:
#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)
That is, row 1 of the br matrix should serve as the breaks for row 1 of the true matrix and for that row only, row 2 of br are the breaks for row 2 of true, etc.
Using the following does not seem to do the work:
for (i in 1:nrow(true)) {
observed[i,]=apply(true[i,],c(1,2),cut,breaks=br[i,],labels=FALSE,include.lowest=TRUE)
}
Do you have any ideas? Is there any way to apply the respective br line to the respective true line and save it in the same line of observed?
Many thanks in advance!
KH
Using sapply
over the number of rows,(essentially just hiding the for loop) gives you what you want:
values = sapply(1:nrow(true), function(i)
cut(true[i,], br[i,], labels=FALSE, include.lowest=TRUE)))
values = t(values)
Unfortunately we need an extra transpose step to get the matrix the correct way.
Regarding your for loop in your question, when you just subset a row, i.e. true[i,]
we just get a vector. This causes the apply
to break. To avoid the vector you need an a additional argument
true[i,, drop=FALSE]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With