2017-12-15 1 views
1

Ich muss sehen, ob eine Liste von Werten in Bereiche von Werten fällt und dann einen bestimmten Wert zuweisen. Ich möchte einen Weg finden, dies zu tun, ohne verschachtelte ifelse() Anweisungen (gerade gelernt ifelse kann nicht mehr als 51-mal nisten und sieht so schrecklich.).Vergleichen Sie die Nummer mit mehreren Vergleichsoperatoren und Werte

Da dies ein künstliches Beispiel ist, frage ich mich, ob es eine verallgemeinerbare Möglichkeit gibt, dies zu tun (z. B. Schleife? * Anwenden)? Ich denke etwas mit paste(eval()) zu tun, kann es aber nicht zur Arbeit bringen. Danke im Voraus.

set.seed(2222) 
comparison_table = data.frame(
    lower_comp = c('>=', '>=', '>='), 
    upper_comp = c('<', '<', '<'), 
    lower_value = c(3, 33, 100), 
    upper_value = c(31, 40, 120), 
    new_value = c(1, 2, 3) 
) 

df = data.frame(
    value = runif(n = 25, min = 1, max = 130) 
) 

df$new_value = with(df, 
    ifelse(value >= 3 & value < 33, 1, 
    ifelse(value >= 33 & value < 100, 2, 
    ifelse(value >= 100 & value < 120, 3, NA)))) 

value   new_value 
48.427905  NA 
24.461992  1 
107.576807  3 
76.461703  NA 
124.694209  NA 
14.132063  1 
98.638509  NA 
32.436195  NA 
88.470441  NA 
9.095131   1 
49.548878  NA 
85.647608  NA 
75.357280  NA 
120.696858  NA 
113.347924  3 
51.364939  NA 
126.896975  NA 
128.282762  NA 
115.333414  3 
75.022578  NA 
128.170932  NA 
2.200451   NA 
24.085131  1 
99.672971  NA 
24.945700  1 
+2

Wenn Ihre Spalten lower_comp und upper_comp immer die gleichen Werte haben, gibt es 'library (data.table); setDT (df); df [comparison_table, on =. (Wert> = lower_value, Wert Frank

Antwort

3

Sie können cut() benutzen, um Ihre Wertvektor aufzuspalten:

df$new_value <- cut(df$value, breaks= c(3,33,100,120),labels=FALSE, right = FALSE) 

Diese drei Intervalle definiert (etwas außerhalb zu NA ausfällt):

[3,33) 
[33,100) 
[100,120) 

Verwenden right = FALSE machen die linke Seite inklusive: Standard ist (x, y] und wir wollen [x, y).

+0

danke für die Hilfe. Das funktioniert definitiv für den Fall, den ich auflege. Ich habe es vermasselt und habe nicht bemerkt, dass die Intervalle "geordnet" sind. Ich habe die Frage aktualisiert. Ich habe versucht, eine Lösung zu finden, die es mir erlaubt, einen String mit den Bedingungen, die ich brauche, einzufügen und mit dem data.frame auszuwerten: 'df $ new_value [parse (eval (text = paste0 ('value > = 3 '))] = 1' zu diesem Teil des Codes compact ..... – bringtheheat

+0

@bringtheheat In diesem Fall würde ich eine kleine Wrapper-Funktion um 'cut()' schreiben und die Eingabe-Ungleichheit mit 'grepl (" > = ", comparison_table $ lower_comp)', und sagen, wenn 'TRUE', dann' right <- FALSE', sonst 'right <- TRUE'. Dann nimm eine Liste deiner Breaks 'unique (c (comparison_table $ lower_value, comparison_table $ upper_value)) ', um nach' breaks' zu wechseln. Dies funktioniert natürlich nur, wenn Ihre Ungleichungen einheitlich sind, dh Sie folgen "> = und <" or "> und <=". – Mako212

+0

@bringtheat In der Praxis würde ich die Vergleichstabelle nicht formatieren Wie du. Ich hätte nur zwei Spalten, eine für die Pausen, und eine, um zu definieren, ob es ein linkes oder rechtes Handintervall ist. – Mako212

Verwandte Themen