在 SAS 中对时间数据进行分类

Categorizing time data in SAS

我有以下数据集:

ID time_bed time_wake hours_sleep
1  00:55:00 08:10:00  07:15:00
2  21:15:00 05:00:00  07:45:00
3  02:00:00 07:50:00  05:50:00

我想将睡眠时间分类为 cat_sleep,如果他们睡的时间多于 7:00:00h,则为 0,如果他们的睡眠时间少于 7,则为1.

data sleep;set final;
time_bed = input(catx(' ',hr_bedhr,hr_bedmin,hr_bedampm),time8.);
time_wake = input(catx(' ',hr_wakehr,hr_wakemin,hr_wakeampm),time8.);
format time_bed time_wake tod8.;
hours_sleep= time_wake - time_bed;
format hours_sleep tod8.;
if hours_sleep >'07:00:00't then cat_sleep=0;
if hours_sleep <= '07:00:00't then cat_sleep=1;
run;

但是,我没有得到想要的输出,如下所示。

ID time_bed time_wake hours_sleep cat_sleep 
1  00:55:00 08:10:00  07:15:00    0 
2  21:15:00 05:00:00  07:45:00    0 
3  02:00:00 07:50:00  05:50:00    1

我试过使用 SAStime,但我得到的是负值,所以我在尝试对其进行分类时遇到了问题。

第一个问题是您无法按照您尝试的方式比较时间,即使用简单的减法运算。

第二个问题是你的值只是时间,没有日期部分。信息的缺乏使准确处理的自动化变得复杂:

第一行,很明显我们有当天的数据

在第 2 行,很明显 time_bed 发生在 time_wake 的前一天,但这与上一行逻辑不同。

那么,如何进行呢?

要比较时间,您必须使用具有适当设置的 SAS 函数 intck,例如:

hours_sleep = intck('minutes', time_bed, time_wake, 'c') / 60;

这个语句应该returns以小时数表示的时差(更多细节请查看intck的文档)

理解起来有点棘手,但在这里您可能需要先估计延迟时间(以分钟为单位),然后除以 60 以获得准确的睡眠持续时间值

为了修复缺失的日期信息,我会在 time_bed > time_wake 时添加 24 小时。

最终代码:

data want;
    set have;
    
    if time_bed > time_wake then time_wake = time_wake + '24:00't;
    
    attrib hours_sleep format=best.;
    hours_sleep = abs(intck('minutes', time_bed, time_wake, 'c') / 60);
    
    if hours_sleep > 7 then flag = 1
    else flag = 0;
run;

如果您已经将睡眠时间作为时间值(自午夜以来的秒数),则只需将其与 7 小时进行比较。

data want;
  set have;
  cat_sleep=not (hours_sleep > '07:00't) ;
run;

如果您需要计算睡眠时间,请将时间值转换为日期时间值,这样您只需减去它们即可得到以秒为单位的差值。如果您假设他们的睡眠时间从不超过 24 小时,那么您可以将就寝时间与起床时间进行比较,以判断起床时间是否为第二天。

data have;
  input ID (time_bed time_wake hours_sleep) (:time.);
  format time_bed time_wake hours_sleep time8. ;
cards;
1  00:55:00 08:10:00  07:15:00
2  21:15:00 05:00:00  07:45:00
3  02:00:00 07:50:00  05:50:00
;

data want;
  set have;
  seconds_asleep = dhms(time_wake<time_bed,0,0,time_wake) - dhms(0,0,0,time_bed);
  format seconds_asleep time8.;
  cat_sleep=not (seconds_asleep > '07:00't) ;
run;

结果:

                            time_      hours_    seconds_     cat_
Obs    ID    time_bed        wake       sleep     asleep     sleep

 1      1     0:55:00     8:10:00     7:15:00     7:15:00      0
 2      2    21:15:00     5:00:00     7:45:00     7:45:00      0
 3      3     2:00:00     7:50:00     5:50:00     5:50:00      1

在行 hours_sleep= time_wake - time_bed; 之后你可以添加一行:

if hours_sleep < 0 then hours_sleep = hours_sleep + '24:00't;

应该去掉 time_bed 午夜之前和 time_wake 午夜之后的底片。