1

我正在尝试使用cut2()中的函数来创建基于时间段的因子。Hmisc

这是一些代码:

library(Hmisc)

i.time <- as.POSIXct("2013-07-16 13:55:14 CEST")
f.time <- i.time+as.difftime(1, units="hours")

data.points <- seq(from=i.time, to=f.time, by="1 sec")
cut.points <- seq(from=i.time, to=f.time, by="60 sec")



intervals <- cut2(x=data.points, cuts=cut.points, minmax=TRUE)

我希望创建间隔,以便将 data.point 中的每个点放置在一个时间间隔中。但最后有一些 NA 值:

> tail(intervals, 1)
[1] <NA>
60 Levels: [2013-07-16 13:55:14,2013-07-16 13:56:14) ... [2013-07-16 14:54:14,2013-07-16 14:55:14]

我期待该选项minmax=TRUE将确保 hte 削减包含data.points.

谁能澄清这里发生了什么?如何使用 cut2 函数生成包含数据中所有值的因子?

4

2 回答 2

5

cut2优先使用的原因cut是它默认的“右”是我期望它工作的方式(左闭区间)。查看代码,我看到当参数列表中存在“cuts”时,该cut函数与一组移位的cuts一起使用,其效果是使间隔左闭,然后代码重新标记要更改的因子"("'s to 's ,["但随后不使用include.lowest = TRUE. 这具有将最后一个值变为 的效果<NA>坦率地说,我认为这是一个错误。在更仔细地查看这个之后,我发现该cut2帮助页面并没有承诺处理任何一个Datedate-time对象,所以“bug”太强大了。对于 Date 对象,它完全失败了,这似乎只是一个意外,对于 POSIXct 对象几乎是正确的。(这个实现让我有些惊讶,因为我一直认为它只是在使用cut( ... , right=FALSE, include.lowest=TRUE).)

您可以更改代码,我的一个想法是通过更改此行将范围扩展回原始数据中的右端点:

r <- range(x,  na.rm = TRUE)

到这一行:

r <- range(c(x,max(x)+min(diff(x.unique))/2),  na.rm = TRUE)

这不是我所期望的结果,因为您在右端获得了一个新类别,因为倒数第二个区间仍然在右侧打开。

intervals <- cut3(x=data.points, cuts=cut.points, minmax=TRUE)
> tail(intervals, 1)
[1] 2013-07-16 14:55:14
61 Levels: [2013-07-16 13:55:14,2013-07-16 13:56:14) ...
> tail(intervals, 2)
[1] [2013-07-16 14:54:14,2013-07-16 14:55:14) 2013-07-16 14:55:14                      
61 Levels: [2013-07-16 13:55:14,2013-07-16 13:56:14) ...

不同的想法会产生更令人满意的结果。仅更改此行:

y <- cut(x, k2)

为此:

y <- cut(x, k2, include.lowest=TRUE)

给出预期的左右闭合区间且没有 NA:

 tail(intervals, 2)
[1] [2013-07-16 14:54:14,2013-07-16 14:55:14] [2013-07-16 14:54:14,2013-07-16 14:55:14]
60 Levels: [2013-07-16 13:55:14,2013-07-16 13:56:14) ...

注意:include.lowest=TRUE 和 right=FALSE,实际上会变成include.highest. 而且我正在摸不着头脑,为什么在这种情况下我实际上得到了所需的行为,而我也不需要使用“正确”参数做某事。我给 Frank Harrell 发了一条消息,他愿意考虑修改代码以处理其他情况。我正在努力。

为什么这是一个问题:标签cut.POSIXt与(实际上)结果cut.Date 的标签不同。前两种标签策略是只复制间隔的开始,而标签来自包括“[”和“)”以及间隔的结束。比较这些输出:cut.numericcut.defaultcut.numeric

levels( cut(0+1:100, 3) )
levels( cut(Sys.time()+1:100, 3) )
levels( cut(Sys.Date()+1:100, 3) )
于 2013-07-16T14:51:11.090 回答
1

来自??cut2

minmax :如果指定了切割但 min(x) < min(cuts) 或 max(x) > max(cuts),则增加切割以包括 min 和 max x

检查你的论点:

x=data.points
cuts=cut.points
r <- range(x, na.rm = TRUE)
 (r[1] < min(cuts) | (r[2] > max(cuts)))
FALSE ## no need to include mean and max

所以这里的设置minmax不要改变结果。但这里使用cutby setting的结果include.lowest=TRUE)

res <- cut(x=data.points, breaks=cut.points, include.lowest=TRUE)
table(is.na(res))
于 2013-07-16T12:30:39.403 回答