2017-06-30 40 views
0

我有15萬個+行的數據幀,但這裏計算經過「次」是什麼,我想實現一個例子:在R,其中時間取決於一個因素

TIME_REAL HR Behaviour 
21:15:00 54 Eupnoea 
21:15:01 107 Eupnoea 
21:15:02 118 Eupnoea 
21:15:03 75 Eupnoea 
21:15:04 94 Eupnoea 
21:15:05 57 Eupnoea 
21:15:06 106 Eupnoea 
21:15:07 121 Eupnoea 
21:15:08 104 Eupnoea 
21:15:09 73 Eupnoea 
21:15:10 114 Apnoea 
21:15:11 108 Apnoea 
21:15:12 121 Apnoea 
21:15:13 117 Apnoea 
21:15:14 110 Apnoea 
21:15:15 38 Eupnoea 
21:15:16 120 Eupnoea 
21:15:17 118 Eupnoea 
21:15:18 82 Eupnoea 
21:15:19 107 Eupnoea 
21:15:20 44 Apnoea 

我想計算行爲事件的持續時間(因子) - 因此第一次的Eupnoea事件會持續9秒,然後是4秒的呼吸暫停事件等等。理想情況下,每次事件發生時我都想要一個單獨的表或列,並且持續時間的行爲事件。我試圖使用dplyr軟件包,但沒有取得任何成功。我還想計算每次行爲事件發生時的平均HR ......無論如何要在R中這樣做?

預先感謝您!

+1

您可以包括的輸出應該是什麼樣子的例子嗎?您還可以包含您所做的失敗代碼。 – aosmith

回答

0

你可以嘗試以下方法:

dff$TIME_REAL <- as.POSIXct(strptime(dff$TIME_REAL, '%H:%M:%S')) 

make_splitter <- function(col_vals) { 
    rle_lengths <- rle(as.character(col_vals))$lengths 
    rep(1:length(rle_lengths), rle_lengths) 
} 

dff %>% 
group_by(splitter = make_splitter(Behaviour), Behaviour) %>% 
summarise(Average_HR = mean(HR), 
     Start_Time = strftime(head(TIME_REAL, 1), '%H:%M:%S'), 
     End_Time = strftime(tail(TIME_REAL, 1), '%H:%M:%S'), 
     Duration = difftime(tail(TIME_REAL, 1), head(TIME_REAL, 1))) 

首先,創建一個功能,可以幫助定義如何分割的數據幀。在這裏,我使用rle函數和一些複製來獲得理想的列。

假設您的當前數據框被稱爲dff,則可以先強制TIME_REAL列爲as.POSIXct對象,然後才能繼續並對其執行任何計算。隨後,您可以使用dplyr分組通過拆分器列和Behavior列,然後使用summarise函數獲取平均HR和平均時間差。

應該產生:

Behaviour Average_HR Start_Time End_Time Duration 
    <fctr>  <dbl>  <chr> <chr> <time> 
1 Eupnoea  90.9 21:15:00 21:15:09 9 secs 
2 Apnoea  114.0 21:15:10 21:15:14 4 secs 
3 Eupnoea  93.0 21:15:15 21:15:19 4 secs 
4 Apnoea  44.0 21:15:20 21:15:20 0 secs 

我希望這有助於。

+0

謝謝你的幫助!不幸的是,我無法讓它工作,因爲行爲是因素....並顯示錯誤消息「max對因素無意義」。我無法將它們變成其他任何東西 - 你知道解決這個問題的方法嗎? – dphil

+0

@dphil,錯誤來自哪裏?當'Behavior'列是一個'factor'時,這裏的代碼工作正常。無論哪種方式,您應該可以在任何'factor'值上臨時使用'as.character'。 – Abdou

+0

我不知道爲什麼它不起作用,但非常感謝你,玩完它後,它完美的作品。有沒有什麼方法可以將開始時間和結束時間添加到這個輸出中(對不起!!)持續時間很長,但也可能存在晝夜效應,我認識到這一點很難從中看出來。 – dphil

0
library(tidyverse) 

tbl <- tribble(
    ~TIME_REAL, ~HR, ~Behaviour, 
    "21:15:00", 54, "Eupnoea", 
    "21:15:01", 107, "Eupnoea", 
    "21:15:02", 118, "Eupnoea", 
    "21:15:03", 75, "Eupnoea", 
    "21:15:04", 94, "Eupnoea", 
    "21:15:05", 57, "Eupnoea", 
    "21:15:06", 106, "Eupnoea", 
    "21:15:07", 121, "Eupnoea", 
    "21:15:08", 104, "Eupnoea", 
    "21:15:09", 73, "Eupnoea", 
    "21:15:10", 114, "Apnoea", 
    "21:15:11", 108, "Apnoea", 
    "21:15:12", 121, "Apnoea", 
    "21:15:13", 117, "Apnoea", 
    "21:15:14", 110, "Apnoea", 
    "21:15:15", 38, "Eupnoea", 
    "21:15:16", 120, "Eupnoea", 
    "21:15:17", 118, "Eupnoea", 
    "21:15:18", 82, "Eupnoea", 
    "21:15:19", 107, "Eupnoea", 
    "21:15:20", 44, "Apnoea" 
) 

myle <- rle(tbl$Behaviour) 
tbl %>% 
    mutate(code = rep(seq_along(myle$values), myle$lengths)) %>% 
    group_by(Behaviour, code) %>% 
    summarise(N = n(), mean = mean(HR)) %>% 
    arrange(code) 
0

以下是如何與dplyr,隨着rleiddata.table幫助。我使用rleid,因爲這是添加組號的簡單方法。我還使用as.POSIXct將時間列轉換爲時間對象,這對操作更簡單。

library(dplyr) 
df %>% 
    mutate(TIME_REAL=as.POSIXct(TIME_REAL,format="%H:%M:%S"), 
      behaviour_number=data.table::rleid(Behaviour))%>% 
    group_by(behaviour_number)%>% 
    summarise(behaviour=max(Behaviour),elapsed=max(TIME_REAL)-min(TIME_REAL), 
      HR_avg=mean(HR,na.rm=TRUE)) 

    behaviour_number behaviour elapsed HR_avg 
      <int>  <chr> <time> <dbl> 
1    1 Eupnoea 9 secs 90.9 
2    2 Apnoea 4 secs 114.0 
3    3 Eupnoea 4 secs 93.0 
4    4 Apnoea 0 secs 44.0 

數據

df <- read.table(text="TIME_REAL HR Behaviour 
21:15:00 54 Eupnoea 
       21:15:01 107 Eupnoea 
       21:15:02 118 Eupnoea 
       21:15:03 75 Eupnoea 
       21:15:04 94 Eupnoea 
       21:15:05 57 Eupnoea 
       21:15:06 106 Eupnoea 
       21:15:07 121 Eupnoea 
       21:15:08 104 Eupnoea 
       21:15:09 73 Eupnoea 
       21:15:10 114 Apnoea 
       21:15:11 108 Apnoea 
       21:15:12 121 Apnoea 
       21:15:13 117 Apnoea 
       21:15:14 110 Apnoea 
       21:15:15 38 Eupnoea 
       21:15:16 120 Eupnoea 
       21:15:17 118 Eupnoea 
       21:15:18 82 Eupnoea 
       21:15:19 107 Eupnoea 
       21:15:20 44 Apnoea",header=TRUE,stringsAsFactors=FALSE) 
0

使用日期時,我建議去lubridate

在這裏,您需要構建一個完整的日期格式以便使用日期。爲了這個例子,我們假設今天是今天。

library(tidyverse) 
try <- tribble(
    ~TIME_REAL, ~Behaviour, 
    "21:15:00", "Eupnoea", 
    "21:15:03", "Eupnoea", 
    "21:15:04", "Eupnoea", 
    "21:15:09", "Eupnoea", 
    "21:15:10", "Apnoea", 
    "21:15:15", "Apnoea", 
    "21:15:17", "Apnoea", 
    "21:15:18", "Apnoea" 
) 
library(lubridate) 
try %>% 
    mutate(TIME_REAL = paste(today(), TIME_REAL)) %>% 
    mutate(TIME_REAL = ymd_hms(TIME_REAL)) %>% 
    group_by(Behaviour) %>% 
    summarize(time = max(TIME_REAL) - min(TIME_REAL)) 


# A tibble: 2 x 2 
    Behaviour time 
     <chr> <time> 
1 Apnoea 8 secs 
2 Eupnoea 9 secs 

這裏兩個mutate調用轉換的日期到ISO8601。然後,你可以group_by和做基本的數學。

希望這可以幫助

科林

相關問題