2017-03-03 2 views
1

Ich habe eine Frage über die Codierung vor wenigen Tagen (Need help code mock sampling). Ich habe bemerkt, dass es zu viel Kontext gibt. Also, von der Post ausgehend, minimiere ich meine Frage. Jede Rückmeldung wird sehr geschätzt.Need hilft bei der Codierung (Text minimiert)

Ich habe Zufallszahl wie folgt aus:

pass.theo <- c(2,4,12,13,14,19,21,27,30,31,32,35,36,38,41,44,49,50,52,57,59,60,61,63,65,68,79,80,86,92,96,100) 

Beginn der ersten Zahl (dh 2) in diesem speziellen Fall würde Ich mag eine Zahl finden, die die erste Zahl, die 5 oder mehr ist als vorherige Elemente (dh 2). In diesem Fall ist die Nummer 12. Und dann von der Nummer 12, ich möchte eine andere erste Nummer finden, die 5 oder größer als ist und bis zum Ende fortfahren. Mit der obigen Nummer habe ich diesen Code manuell generiert, benötige jedoch Code für die Durchführung im Allgemeinen.

tf <- c(
pass.theo[2]-pass.theo[1] > 5, # 
pass.theo[3]-pass.theo[1] > 5, # select 
pass.theo[4]-pass.theo[3] > 5, # 
pass.theo[5]-pass.theo[3] > 5, # 
pass.theo[6]-pass.theo[3] > 5, # select 
pass.theo[7]-pass.theo[6] > 5, # 
pass.theo[8]-pass.theo[6] > 5, # select 
pass.theo[9]-pass.theo[8] > 5, 
pass.theo[10]-pass.theo[8] > 5, 
pass.theo[11]-pass.theo[8] > 5, 
pass.theo[12]-pass.theo[8] > 5, # select 
pass.theo[13]-pass.theo[12] > 5, 
pass.theo[14]-pass.theo[12] > 5, 
pass.theo[15]-pass.theo[12] > 5, # select 
pass.theo[16]-pass.theo[15] > 5, 
pass.theo[17]-pass.theo[15] > 5, # select 
pass.theo[18]-pass.theo[17] > 5, 
pass.theo[19]-pass.theo[17] > 5, 
pass.theo[20]-pass.theo[17] > 5, # select 
pass.theo[21]-pass.theo[20] > 5, 
pass.theo[22]-pass.theo[20] > 5, 
pass.theo[23]-pass.theo[20] > 5, 
pass.theo[24]-pass.theo[20] > 5, # select 
pass.theo[25]-pass.theo[24] > 5, 
pass.theo[26]-pass.theo[24] > 5, 
pass.theo[27]-pass.theo[24] > 5, # select 
pass.theo[28]-pass.theo[27] > 5, 
pass.theo[29]-pass.theo[27] > 5, # select 
pass.theo[30]-pass.theo[29] > 5, # select 
pass.theo[31]-pass.theo[30] > 5, 
pass.theo[32]-pass.theo[30] > 5 # select 
) 
tf 
passes <- c(pass.theo[1], pass.theo[-1][tf]) 

expected.select <- ifelse(pass.theo %in% passes, 'select', 'drop') 
cbind(pass.theo, expected.select) 
     pass.theo expected.select 
# [1,] "2"  "select"  
# [2,] "4"  "drop"   
# [3,] "12"  "select"  
# [4,] "13"  "drop"   
# [5,] "14"  "drop"   
# [6,] "19"  "select"  
# [7,] "21"  "drop"   
# [8,] "27"  "select"  
# [9,] "30"  "drop"   
#[10,] "31"  "drop"   
#[11,] "32"  "drop"   
#[12,] "35"  "select"  
#[13,] "36"  "drop"   
#[14,] "38"  "drop"   
#[15,] "41"  "select"  
#[16,] "44"  "drop"   
#[17,] "49"  "select"  
#[18,] "50"  "drop"   
#[19,] "52"  "drop"   
#[20,] "57"  "select"  
#[21,] "59"  "drop"   
#[22,] "60"  "drop"   
#[23,] "61"  "drop"   
#[24,] "63"  "select"  
#[25,] "65"  "drop"   
#[26,] "68"  "drop"   
#[27,] "79"  "select"  
#[28,] "80"  "drop"   
#[29,] "86"  "select"  
#[30,] "92"  "select"  
#[31,] "96"  "drop"   
#[32,] "100"  "select" 

Ich möchte das erste Element immer einschließen und wählen Sie tf == TRUE aus dem Rest von pass.theo.

passes 

Gibt es eine Möglichkeit, eine Funktion höher zu machen?

Vielen Dank im Voraus !!!

+3

*“ finde Zahlen th bei sind 5 oder größer als die vorherigen Elemente "* wäre einfach" diff (pass.theo)> 5 ", aber das stimmt nicht mit Ihrem Code überein. Klingt wie Ihre Logik ist ein bisschen komplizierter als das. – r2evans

+0

So scheint es, dass der Index, der subtrahiert wird, sich ändert, wenn eine Berechnung TRUE zurückgibt. –

+0

Danke für Kommentare. Ich habe versucht, oben mehr zu klären. Zum Beispiel, wenn ich eine erste Zahl (d. H. 12) finde, die 5 oder größer als die Zahl 2 ist. Dann möchte ich sie aus der Zahl 12 wiederholen, so dass die nächste Zahl 19 usw. ist. – Steve

Antwort

2
pass.theo <- c(2,4,12,13,14,19,21,27,30,31,32,35,36,38,41,44,49,50,52,57,59,60,61,63,65,68,79,80,86,92,96,100) 
# to keep the original pass.theo untouched 
dat <- pass.theo 
for (i in seq_along(pass.theo)[-1]) { 
    if ((dat[i] - dat[i-1]) < 5) dat[i] <- dat[i-1] 
} 
ret <- c(FALSE, diff(dat) >= 5) 

Zur Demonstration, ich werde sie binden, so können Sie sehen, was passiert ist:

data.frame(pass.theo = pass.theo, mod = dat, ret = ret) 
# pass.theo mod ret 
# 1   2 2 FALSE 
# 2   4 2 FALSE 
# 3   12 12 TRUE 
# 4   13 12 FALSE 
# 5   14 12 FALSE 
# 6   19 19 TRUE 
# 7   21 19 FALSE 
# 8   27 27 TRUE 
# 9   30 27 FALSE 
# 10  31 27 FALSE 
# 11  32 32 TRUE 
# 12  35 32 FALSE 
# 13  36 32 FALSE 
# 14  38 38 TRUE 
# 15  41 38 FALSE 
# 16  44 44 TRUE 
# 17  49 49 TRUE 
# 18  50 49 FALSE 
# 19  52 49 FALSE 
# 20  57 57 TRUE 
# 21  59 57 FALSE 
# 22  60 57 FALSE 
# 23  61 57 FALSE 
# 24  63 63 TRUE 
# 25  65 63 FALSE 
# 26  68 68 TRUE 
# 27  79 79 TRUE 
# 28  80 79 FALSE 
# 29  86 86 TRUE 
# 30  92 92 TRUE 
# 31  96 92 FALSE 
# 32  100 100 TRUE 

Ich bin kein Fan von iterativ den Vektor wie dies zu ändern, aber ich weiß nicht von andere Werkzeuge, die den Vektor korrekt abrollen.

Edit:

Eigentlich Inspiration Einnahme von @ MrFlick der Reduce (gedacht, dass haben sollte), können Sie die for Schleife mit ersetzen:

dat2 <- Reduce(function(a,b) if ((b-a)<5) a else b, 
       pass.theo, accumulate = TRUE) 

Dann

c(FALSE, diff(dat2) >= 5) 

ist das gleiche wie meine ret oben. (Ich bin nicht zu stehlen @ MrFlick Antwort versuchen, soll er Kredit nimmt für das Vorschlagen Reduce über meine schlampig/ineffizient for Schleife.

+1

Sie haben den Reduce-Anruf wirklich aufgeräumt, also bin ich absolut einverstanden. – MrFlick

+1

Ich lehne mich oft zu 'zoo :: rolllapply' anfänglich für sowas an, aber es sammelt sich * nicht so an, wie ich es mir erhofft habe. Ich fühle mich wie "Reduce (..., accumulate = TRUE)" ist so eine unterschätzte rollende Funktion mit diesem Argument. (Die Tatsache, dass 'Reduce' eine 'for'-Schleife unter der Haube macht, ist eine Technik, die ich akzeptieren muss :-) – r2evans

+0

Hi r2evans. Das ist toll!!! Ich werde aber Zeit brauchen, um deinen Code zu verstehen. Vielen Dank für Ihre Hilfe und alle anderen für Kommentare !!! – Steve

2

Hier ist ein Verfahren unter Verwendung Reduce()

pp<-which(sapply(Reduce(function(a,b) { 
    aa <- a[[1]] 
    if (b-aa>5) { 
     return(list(b, T)) 
    } else { 
     return(list(aa, F)) 
    } 
}, pass.theo, init=list(pass.theo[1],F), accumulate=T), `[[`, 2)) - 1 
passes <- c(pass.theo[1], pass.theo[pp]) 

Im Grunde habe ich Reduce() paarweise zu Schritt durch die Elemente, während sie entlang dem aktuellen niedrigsten Wert übergeben. I sapply() dann die Werte zu extrahieren verwenden, um, wenn ein Wechsel which() aufgetreten ist, und verwenden, um die Indizes zu erhalten (Subtrahieren von 1, weil ich einen Anfangswert in dem Reduce Anruf verwendet wird).

+0

Vielen Dank für Ihre Hilfe, MrFlick !!! – Steve