2016-08-14 5 views
2

Ich brauche den größten gemeinsamen Teiler (GCD) für eine Reihe von Dauern zu finden: dur.R - größte gemeinsame Divisor dplyr Routine

Aussehen Meine Daten wie diese

  actrec dur 
1 c Personal Care 120 
2  c Free Time 10 
3  c Free Time 70 
4  c Free Time 40 
5   b Unpaid 10 
6  c Free Time 20 
7 c Personal Care 30 
8  c Free Time 40 
9  c Free Time 40 
10  c Free Time 10 

ich die Funktion gcd der schoolmath Bibliothek verwenden. Ich gehe meine Daten durch und speichere die Werte im Vektor v. Schließlich verwende ich die min von v, um den gcd meiner Daten zu finden.

library(schoolmath) 

l = length(dt$dur) 
v = array(0, l) 

for(i in 2:l){ 
    v[i] = gcd(dt$dur[i], dt$dur[i-1]) 
} 

minV = min(v[-1]) 
minV 

Welche 10 gibt.

Allerdings habe ich Probleme, diese Routine in dplyr zu übersetzen.

Ich dachte an etwas wie (lag für Schleife).

dt %>% mutate(gcd(dur, lag(dur, 0))) 

Aber es funktioniert nicht. Und ich bin unsicher, wie man min einfügt.

Irgendwelche Hinweise?

+0

Sieht aus wie die 'gcd' nicht vektorisiert ist. Vielleicht 'dt%>% mutiere (dur1 = lag (dur, default = dur [1]))%>% reihenweise()%>% muate (new1 = gcd (dur, dur1)) ' – akrun

+1

Hier ist eine vektorisierte Version von gcd das könnte hilfreich sein http://stackoverflow.com/a/21504113/3001626 –

+0

danke interessant – giacomo

Antwort

2

Wir rowwise verwenden können die gcd Funktion in jeder Zeile anzuwenden, nachdem die lag von ‚dur, extrahieren Sie die‚new1‘und erhalten die min

dt %>% 
    mutate(dur1 = lag(dur, default = dur[1])) %>% 
    rowwise() %>% 
    mutate(new1 = gcd(dur, dur1)) %>% 
    .$new1 %>% 
    tail(.,-1) %>% 
    min 
#[1] 10 

Oder wir schaffen eine Vectorize d Funktion unter von 'gcd' und gelten auf der 'dur' Spalte

gcdV <- Vectorize(function(x,y) gcd(x, y)) 
dt %>% 
    mutate(new1 = gcdV(dur, lag(dur, default = dur[1]))) 

und die min wie in t erhalten er über der Lösung.

+1

danke - tolle antwort. Ich bin wirklich überrascht, dass der Code so lang sein muss. – giacomo

+1

@giacomoV Ich extrahierte das 'min' als einen einzelnen Wert. Wenn du als data.frame willst, könnte es 'dt%>% summieren (Min = min (gcdV (dur, lag (dur, default = dur [1])) [- 1]))' – akrun

+1

Danke! – giacomo

Verwandte Themen