2017-01-26 12 views
1

liegen. Ich muss Codes, die verschiedene Krankheiten repräsentieren, neu kategorisieren, um geeignete Gruppen für die spätere Analyse zu bilden.Überprüfen Sie, ob Dezimalwerte in einem Bereich in R

Viele der Gruppierungen umfassen Bereiche, die wie folgt aussehen:

1.0 to 1.5, 1.8 to 2.5, 3.0 

, wo eine andere sein könnte 37.0

Ursprünglich dachte ich, dass so etwas wie dies funktionieren könnte:

x <-c(0:.9, 1.9:2.9, 7.9:8.9, 4.0:4.9, 3:3.9, 5:5.9, 6:6.9, 11:11.9, 9:9.9, 10:10.9, 12.9, 13:13.9, 14,14.2, 14.8) 

df$disease_cat[df$site_code %in% x] <- "disease a" 

Das Problem ist, 0.1,0.2 usw. werden nicht als in dem Bereich von 0:0.9 liegend erkannt.

Ich verstehe jetzt, dass 5:10 (zum Beispiel) in r tatsächlich 5,6,7...10

Was ist ein besserer Weg, um diese Intervalle zu codieren, so dass die Dezimalstellen werden 0-0.9 als im Intervall erkannt werden? (Wenn man bedenkt, dass es viele „Mini“ Bereiche liegen und die Idee der Codierung sie alle explizit nicht besonders ansprechend ist)

+0

Diese ersten 2 Antworten funktionieren in diesem Fall, aber was ich nicht genauer spezifiziert habe, ist, dass ich daran interessiert bin, eine Liste verschiedener Bereiche zu erstellen, um eine Anzahl von Dis neu zu codieren verschiedene Werte, die Dezimalzahlen enthalten. Gibt es eine effizientere Methode, um herauszufinden, ob Werte in einem Bereich (einschließlich Dezimalstellen) liegen? – Jacob

+0

@Jacob Bitte bearbeiten Sie Ihre Frage und spezifizieren Sie, was genau Sie brauchen. – Ardavel

+1

Ich nehme an, dass es keine andere Möglichkeit gibt, sie zu definieren, also denke ich, dass ich so vorgehen werde: c (seq (0, .9, by = .1), (seq (5.6.5.9, by =. 1)) usw., es sei denn jemand denkt, dass es einen besseren Weg gibt – Jacob

Antwort

1

Sie können die Antwort finden, indem Sie den Inhalt von c(1.1:4) drucken. Das Ergebnis ist [1] 1.1 2.1 3.1. Was Sie brauchen, ist findInterval Funktion. Schauen Sie sich diese Lösung:

findInterval(c(1,2,3,4.5), c(1.1,4)) == 1

Wenn Sie die inklusive rechte Grenze haben möchte, i. e. [1,1, 4] Intervall können Sie rightmost.closed Parameter verwenden:

findInterval(c(1,2,3,4.5), c(1.1,4), rightmost.closed = TRUE) == 1

EDIT:

Hier ist die Lösung für ein allgemeineres Problem, das Sie beschrieben haben:

d = data.frame(disease = c('d1', 'd2', 'd3'), minValue = c(0.3, 1.2, 2.2), maxValue = c(0.6, 1.9, 2.5)) 
measurements = c(0.1, 0.5, 2.2, 0.3, 2.7) 

findDiagnosis <- function(data, measurement) { 
    diagnosis = data[data$minValue <= measurement & measurement <= data$maxValue,] 
    if (nrow(diagnosis) == 0) { 
    return(NA) 
    } else { 
    return(diagnosis$disease) 
    } 
} 

sapply(measurements, findDiagnosis, data = d) 
+0

Dank Ardavel, änderte ich mich Frage besser zu reflektieren, was ich suche – Jacob

+0

@Jacob Ich habe gerade meine Antwort aktualisiert, um das erweiterte Problem zu lösen. – Ardavel

+0

Cool, ich hatte nicht darüber nachgedacht, es so zu machen, Danke! – Jacob

1

Ich glaube, Sie wollen, dass diese:

c(1,2,3,4.5) >= 1.1 & c(1,2,3,4.5) <= 4 
[1] FALSE TRUE TRUE FALSE 

die Ausgabe von 1.1:4 untersuchen:

1.1:4 
[1] 1.1 2.1 3.1 

Sie sind tatsächlich testen, ob Elemente aus dem Vektor sind genau gleich 1.1, 2.1 oder 3.1

1
#This the list of your ranges that you want to check 
ranges = list(c(0,.9), c(1.9,2.9), c(7.9,8.9), c(4.0,4.9), c(3,3.9), c(5,5.9), c(6,6.9), c(11,11.9), c(9,9.9), c(10,10.9), c(12.9), c(13,13.9), c(14),c(14.2), c(14.8)) 

#This is the values that you want to check for each range in ranges 
values = c(1,2,3,4.5) 

#You can check each value in each range with following command 
output = data.frame(t(sapply(ranges, function(x) (min(x)<values & max(x)>values)))) 

#Maybe set column names to values so you know clearly what you are checking. 
#Column names are values, row names are indexes of the ranges 
colnames(output) = values 
output$ranges = sapply(ranges, function(x) paste(x,collapse = "-")) 
Verwandte Themen