2015-01-29 4 views
5

Vorrei trasformare una matrice di punteggi latenti in punteggi osservati.R: Applica il taglio utilizzando le interruzioni specifiche per riga

Si può fare ciò applicando punti di interruzione/soglie alla matrice originale, finendo così per avere una nuova matrice categoriale. In questo modo è semplice, per esempio:

#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) 

Tuttavia, cosa devo fare è applicare diverse pause per ogni riga della matrice origine. Queste soglie sono memorizzati in una matrice:

#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) 

Cioè, riga 1 della br matrice dovrebbe servire le interruzioni di riga 1 della vera matrice e per quella riga solo, riga 2 di br sono le pause per riga 2 del vera, ecc

utilizzando la seguente non sembra fare il lavoro:

for (i in 1:nrow(true)) { 
    observed[i,]=apply(true[i,],c(1,2),cut,breaks=br[i,],labels=FALSE,include.lowest=TRUE) 
} 

Avete qualche idea? C'è un modo per applicare la rispettiva linea alla rispettiva linea vera e salvarla nella stessa riga osservata?

Molte grazie in anticipo!

KH

risposta

1

Utilizzando sapply sopra il numero di righe, (essenzialmente solo nascondere il ciclo for) ti dà ciò che si vuole:

values = sapply(1:nrow(true), function(i) 
    cut(true[i,], br[i,], labels=FALSE, include.lowest=TRUE))) 
values = t(values) 

Purtroppo abbiamo bisogno di un passaggio di trasposizione in più per ottenere la matrice nel modo corretto.


quanto riguarda il tuo ciclo for nella sua interrogazione, quando basta sottoinsieme A di fila, vale a dire true[i,] otteniamo appena un vettore. Ciò causa l'interruzione di apply. Per evitare il vettore è necessario un argomento aggiuntivo

true[i,, drop=FALSE] 
+0

Grazie anche a te per la tua risposta! Funziona alla grande anche velocemente. – user4507481

1

Alcuni programmazione funzionale e Map fare il trucco:

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 
+0

Grande, grazie! Funziona molto velocemente! – user4507481

+0

Ho trovato la tua domanda una meraviglia per la mappa! O la mappa è una meraviglia per questo tipo di domande! –