我有一组观察对,我想用它们time
之间的间隔标记。 (在真实数据集中,这些观察对代表进入和退出麦克风校准。)
# 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
我在此示例中包含一个虚拟someAttribute
,以强调像tidyr::spread()
这样的简单解决方案会使属于data
中每行的属性变得混乱。
我有一个制作间隔的函数,我按照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
这些值不是我预期得到的。正确的时间传递给我的函数,它为返回创建了正确的双元素向量间隔,但是当这个向量传递回mutate
时,会发生一些不好的事情。仔细看看:
str(data2$intervals)
## Formal class 'Interval' [package "lubridate"] with 3 slots
## ..@ .Data: num [1:6] 1 1 3 3 6 6
## ..@ start: POSIXct[1:2], format: "2016-06-01 01:00:00" "2016-06-01 01:00:00"
## ..@ tzone: chr "UTC"
我不清楚这里出了什么问题。这些是我想看到的结果:
## 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
任何人都可以提供一些有关出错的信息,或者我如何才能达到预期效果?我是否误用了mutate
,还是仅仅设计用于处理lubridate::Interval
等对象?
答案 0 :(得分:1)
这是基于@ Arun的data.table
解决方法(#1777)的解决方法,但是使用dplyr
语言:
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
不完全令人满意,但它确实有效。感谢小费,@ Arun。