使用lubridate :: hhmm格式的dplyr过滤使用minute()

时间:2017-08-21 16:00:20

标签: r filter dplyr lubridate

回答这个问题Temperature curve in R我遇到了dplyr::filter - lubridate::minute组合的奇怪行为。

请参阅下面的测试数据dtadta$timelubridate::hhmm格式。

library(lubridate)
library(dplyr)

dta$Time <- hm(dta$Time)

要仅获取完整小时(即0分钟)的行,可以使用lubridate::minute进行子集,如下所示:

dta[minute(dta$Time) == 0,]
#        Time    Temp1    Temp2
# 1        0S 18.62800 18.54458
# 7  1H 0M 0S 18.45733 18.22625
# 13 2H 0M 0S 18.33258 18.04142

但是,使用dplyr&#39; filter时,就像这样

dta %>% filter(minute(Time) == 0)
#     Time    Temp1    Temp2
# 1     0S 18.62800 18.54458
# 2 10M 0S 18.45733 18.22625
# 3 20M 0S 18.33258 18.04142

结果并不符合预期。 (更新Temp1Temp2的值是正确的,只有Time已损坏...感谢@Brian btw提供此提示。)

此外,还会返回此警告:

  

Warning message: In format.data.frame(x, digits = digits, na.encode = FALSE) : corrupt data frame: columns will be truncated or padded with NAs

这也被报道并以某种方式解决here,但只是通过强制,这似乎消除了lubridate的乐趣(和非常可读)部分。

问题:有没有任何方法(迄今为止)dplyr::filter lubridate::hhmm(ss)格式而不强迫其加入角色等?

更新

似乎是由

创建的矢量
minute(dta$Time)
# [1]  0 10 20 30 40 50  0 10 20 30 40 50  0

看起来像一个数字向量,但似乎有一些神秘的特征。

此外,正如@Lyngbakr所指出的那样,即使与==的比较也不具备通常的特征,因为正常情况下#34;逻辑向量。

tst <- minute(dta$Time) == 0 
dta %>% filter(tst)

会产生同一个奇怪的Time列。

样本数据:

dta <- read.table(text = "     Time        Temp1       Temp2
                           1  00:00     18.62800    18.54458
                           2   00:10     18.60025    18.48283
                           3   00:20     18.57250    18.36767
                           4   00:30     18.54667    18.36950
                           5   00:40     18.51483    18.36550
                           6   00:50     18.48325    18.34783
                           7   01:00     18.45733    18.22625
                           8   01:10     18.43767    18.19067
                           9   01:20     18.41583    18.22042
                           10  01:30     18.39608    18.21225
                           11  01:40     18.37625    18.18658
                           12  01:50     18.35633    18.05942
                           13  02:00     18.33258    18.04142", header = T)

1 个答案:

答案 0 :(得分:1)

我不知道为什么会这样,但确实如此:Time列必须是datetime类型,而不是Period

dta %>% 
  mutate(Time = as_datetime(hm(Time))) %>% 
  filter(minute(Time) == 0) 
                 Time    Temp1    Temp2
1 1970-01-01 00:00:00 18.62800 18.54458
2 1970-01-01 01:00:00 18.45733 18.22625
3 1970-01-01 02:00:00 18.33258 18.04142

这样做的副作用就是将Time列中的时间添加到Unix时代,因此我建议您在使用仅限时间的数据时始终包含实际日期。

如果这是从实验开始以来经过的几分钟,那真的不重要,你不必显示1970-01-01部分。