2016-08-01 10 views
5

Użycie R, próbuję obliczyć całkowity czas trwania dla każdej osoby, gdy ten czas trwania jest czasem spędzonym powyżej pewnego progu.Jak obliczyć całkowity czas trwania koncentracji przekraczającej próg wielokrotnie?

Na przykład na poniższym wykresie mam dane dotyczące stężenia dla 3 osób (ID) i chciałbym znaleźć czas (oś x) spędzony nad niebieską linią przerywaną dla każdej osoby. zestaw danych struktura byłoby coś jak:

head(dataset) 
    ID time  CP 
1 1 0.0 0.00000000 
2 1 0.0 0.00000000 
3 1 0.5 0.03759806 
4 1 1.0 0.12523455 
5 1 1.5 0.23483219 
6 1 2.0 0.34820905 

Solid lines represent the concentrations for 3 different subjects

Próbuję użyć następującego kodu:

library(data.table) 
TAbove<-setDT(dataset)[CP > .05, diff(range(time)), by = ID] 

Jednak ten kod, który oblicza czas trwania od pierwszego wzroście powyżej przerywana niebieska linia do ostatniej kropli. Na przykład dla zielonego ID linii, patrz czarna linia.

enter image description here

Jak mogę napisać kod, który bierze pod uwagę czasy, w których stężenie spada poniżej linii przerywanej, wyłączając je. końcowy wynik byłby całkowitym czasem trwania wszystkich czasów powyżej przerywanej niebieskiej linii. jak poniżej

enter image description here

+0

Zobacz "? Rle". Ignorowanie wielu identyfikatorów w danym momencie, mając, powiedzmy, 'x = sin (seq (-3 * pi, 3 * pi, 0.1)) i obliczanie' r = rle (x> próg) ', pozycje początkowa i końcowa następujących po sobie 'TRUE's (tj.' x> threshold') to 's = cumsum (c (1, r $ lengths)) [r $ wartości]' i 'e = i + r $ lengths [r $ values] - 1', odpowiednio. Podsumowując 'czas [e] - czas [s]' powinien dać całkowity czas gdzie próg 'x>. –

Odpowiedz

1

Dzięki rycerzowi za udzielenie pomysłu na rozwiązanie tego problemu. poniższy kod pomógł mi przeprowadzić analizę, jednak musiałem dodać zmienną o nazwie "Dzień", a następnie obliczyć czas trwania na dzień. Tutaj użyłem dnia, ponieważ istnieje jeden interwał na dzień. Ale możesz dostosować go do swoich potrzeb.

#sub-setting by day 
dataset$Day[dataset$time>=0 &dataset$time<24] <- "Day 1" 
dataset$Day[dataset$time>=24 &dataset$time<48] <- "Day 2" 
dataset$Day[dataset$time>=48 &dataset$time<72] <- "Day 3" 
#per day# 
TAbove<-setDT(dataset)[CP > .05, diff((time)), by = .(ID,Day)] 
library(plyr) 
# sum the time duration for each day per person 
sumPerDay<-summarise(group_by(TAbove, ID,Day), 
      sum=sum(V1)) 
# sum the time duration for ALL days per person 
sumAll<-summarise(group_by(TAbove, ID), 
       sum=sum(V1)) 
2

Myślę, że rozwiązaniem jest prawie idealny, po prostu opuścić range. Próbowałem następujących na rozszerzonym zbiorze danych (dodano kilka Wpisy)

> dat <- fread("ID time  CP 
+    1 0.0 0.00000000 
+    1 0.0 0.00000000 
+    1 0.5 0.03759806 
+    1 1.0 0.12523455 
+    1 1.5 0.23483219 
+    1 2.0 0.34820905 
+    1 3.0 0.5 
+    2 0.0 0.5 
+    2 0.5 0.01 
+    2 1.0 0.2") 

z następującym wynikiem:

> dat[CP > .05, diff(time), by = ID] 
    ID V1 
1: 1 0.5 
2: 1 0.5 
3: 1 1.0 
4: 2 1.0 

Edit: Obliczanie z oryginalnymi danymi ustawić

Stosując oryginalne dane zestaw

dataset <- fread("ID time  CP 
        1 0.0 0.00000000 
        1 0.0 0.00000000 
        1 0.5 0.03759806 
        1 1.0 0.12523455 
        1 1.5 0.23483219 
        1 2.0 0.34820905") 

otrzymujemy e następujący wynik:

> dataset[CP > .05, diff(time), by = ID] 
    ID V1 
1: 1 0.5 
2: 1 0.5 
+0

Z jakiegoś powodu kod daje mi inną odpowiedź. ID V1 1: 1 0,5 2: 1 0,5 3: 1 0.5 4: 1 0,5

+0

Może ponownym uruchomieniu sesji R lub aktualizacji do najnowszej wersji 'data.table' pomaga.Wystarczy dwukrotnie sprawdzić moje rozwiązanie i działa ono na moim komputerze z najnowszą wersją R, 'data.table' i nową sesją R. – rhole

+0

Przepraszam, wypróbowałem, ale wciąż dałem mi inne wyniki. Czy mógłbyś napisać kod, którego używałeś? –

Powiązane problemy