在 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 午夜之后的底片。
我有以下数据集:
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 午夜之后的底片。