2016-07-29 31 views
1

Ich habe eine Reihe von Beobachtungspaaren, die ich mit den Intervallen zwischen ihren time s beschriften möchte. (In der realen Datensatzes, diese Paare Beobachtung darstellen Eintritts- und Austritts Mikrofon Kalibrierungen.)Gruppierte dplyr :: mutate gibt Vektoren von lubridate Intervallen falsch

# R version 3.2.3 
library(lubridate) ## Version 1.5.6 
library(dplyr) ## Version 0.5.0 

data <- data.frame(
    group = c(1,1,2,2,3,3), 
    type = rep(c("start", "end"), 3), 
    time = ymd_hms("2016-06-01 01:00:00") + c(0,1,3,6,12,18), 
    someAttribute = runif(6) 
) 

data 
## group type    time someAttribute 
## 1  1 start 2016-06-01 01:00:00  0.2540128 
## 2  1 end 2016-06-01 01:00:01  0.6845078 
## 3  2 start 2016-06-01 01:00:03  0.3576477 
## 4  2 end 2016-06-01 01:00:06  0.1223582 
## 5  3 start 2016-06-01 01:00:12  0.2715063 
## 6  3 end 2016-06-01 01:00:18  0.6392607 

I enthalten eine Dummy-someAttribute in diesem Beispiel zu betonen, dass eine einfache Lösung, wie tidyr::spread() ein Durcheinander der Attribute machen würde, die zu gehören, jede Reihe in data.

Ich habe eine Funktion, die die Intervalle macht, und ich wenden sie durch Gruppe mit dplyr:

makeTwoIntervals <- function(twoDatetimes) { 
    return(rep(interval(twoDatetimes[1], twoDatetimes[2]), 2)) 
} 

data2 <- data %>% group_by(group) %>% mutate(intervals = makeTwoIntervals(time)) 

data2$intervals 
## [1] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [2] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [3] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:03 UTC 
## [4] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:03 UTC 
## [5] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:06 UTC 
## [6] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:06 UTC 

Diese Werte sind nicht das, was ich zu bekommen erwartet. Die richtigen Zeiten werden an meine Funktion übergeben, und es erstellt den richtigen Zwei-Element-Vektor von Intervallen für die Rückgabe, aber wenn dieser Vektor an mutate zurückgegeben wird, passiert etwas Schlimmes. Genau betrachtet:

Es ist mir nicht klar, was hier schief gelaufen ist. Dies sind die Ergebnisse, die ich sehen wollte:

## Desired result of data2$intervals: 
## [1] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [2] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [3] 2016-06-01 01:00:03 UTC--2016-06-01 01:00:06 UTC 
## [4] 2016-06-01 01:00:03 UTC--2016-06-01 01:00:06 UTC 
## [5] 2016-06-01 01:00:12 UTC--2016-06-01 01:00:18 UTC 
## [6] 2016-06-01 01:00:12 UTC--2016-06-01 01:00:18 UTC 

Könnte jemand bieten einen Einblick in das, was schief gelaufen ist, oder wie könnte ich das gewünschte Ergebnis erreichen? Verwende ich mutate, oder ist es nur nicht für Objekte wie lubridate::Interval entworfen?

+0

Dies wurde kürzlich als Problem [# 1777] (https://github.com/Rdatatable/data.table/issues/1777) auf der data.table-Projektseite ebenfalls eingereicht, und ich empfehle eine Problemumgehung dort . – Arun

Antwort

1

Dies ist eine Abhilfe basiert auf @data.table Abhilfe des Arun (#1777), aber in dplyr Sprache:

data2 <- data %>% group_by(group) %>% mutate(ranges = list(range(time))) 
data3 <- data2 %>% mutate(intervals = list(interval(ranges[[1]][1], ranges[[1]][2]))) 
data3$intervals2 <- do.call("c", data3$intervals) 

data3$intervals2 
## [1] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [2] 2016-06-01 01:00:00 UTC--2016-06-01 01:00:01 UTC 
## [3] 2016-06-01 01:00:03 UTC--2016-06-01 01:00:06 UTC 
## [4] 2016-06-01 01:00:03 UTC--2016-06-01 01:00:06 UTC 
## [5] 2016-06-01 01:00:12 UTC--2016-06-01 01:00:18 UTC 
## [6] 2016-06-01 01:00:12 UTC--2016-06-01 01:00:18 UTC 

nicht völlig zufriedenstellend, aber es funktioniert. Danke für den Tipp, @Arun.