2015-01-29 9 views
5

Ich möchte eine Matrix von latenten Scores in beobachtete Scores transformieren.R: Schnitt mit zeilenspezifischen Brüchen anwenden

Man kann dies tun, indem man Breakpoints/Schwellenwerte auf die ursprüngliche Matrix anwendet und so eine neue kategoriale Matrix erhält. Dadurch ist einfach, zum Beispiel:

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

jedoch, was ich tun muß, ist verschiedene Pausen jede Zeile der ursprünglichen Matrix gelte. Diese Schwellenwerte werden in einer Matrix gespeichert:

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

Das heißt, Zeile 1 des br Matrix als Pause für Zeile 1 der wahren Matrix und für diese Zeile dienen sollte nur, Reihe 2 von br sind die Pausen für Zeile 2 von wahr usw.

die folgende Verwendung scheint nicht die Arbeit zu tun:

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

Haben Sie irgendwelche Ideen? Gibt es eine Möglichkeit, die jeweilige Br-Linie auf die jeweilige wahre Linie anzuwenden und sie in der gleichen beobachteten Linie zu speichern?

Vielen Dank im Voraus!

KH

Antwort

1

sapply über die Anzahl der Zeilen verwenden, (im wesentlichen nur die for-Schleife versteckt) gibt Ihnen, was Sie wollen:

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

Leider benötigen wir einen zusätzlichen Transponierungsschritt, um die Matrix auf die richtige Weise zu erhalten.


In Bezug auf Ihre in Ihrer Frage Schleife, wenn Sie eine Zeile nur Teilmenge, das heißt true[i,] wir einen Vektor nur bekommen. Dies führt dazu, dass die apply bricht. Um den Vektor zu vermeiden, benötigen Sie ein zusätzliches Argument

true[i,, drop=FALSE] 
+0

Vielen Dank auch für Ihre Antwort! Funktioniert auch super schnell. – user4507481

1

Einige der funktionalen Programmierung und Map der Trick:

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

Großartig, danke! Funktioniert sehr schnell! – user4507481

+0

Ich fand Ihre Frage ein Wunder für Map! Oder Karte ist ein Wunder für diese Art von Frage! –

Verwandte Themen