【问题标题】:Grouped dplyr::mutate incorrectly returns vectors of lubridate intervals分组 dplyr::mutate 错误地返回 lubridate 间隔向量
【发布时间】:2016-07-29 05:49:44
【问题描述】:

我有一组观察对,我想用它们的times 之间的间隔来标记它们。 (在真实数据集中,这些观察对代表进入和退出麦克风校准。)

# 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 之类的对象?

【问题讨论】:

  • 这是最近在 data.table 项目页面上作为问题 #1777 提交的,我建议在那里解决问题。

标签: r dplyr s4 lubridate


【解决方案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 的提示。

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多