根据日期字段按年份对汇总统计信息进行分组
Group summary statistics by year based on a date field
我知道那些关注 SAS 标签的人已经习惯了这个论坛上一些非常高级的东西。我现在只是想学习我的基础知识,并根据我使用 SQL 或只是 Excel 的经验来思考。我想知道如何按日期列的年份部分进行分组。我做了一些 Google 搜索并迷路了。
如果我有这样的样本数据集:
Date Close Volume
12/31/2014 222.41 2402097
12/30/2014 222.23 2903242
12/29/2014 225.71 2811828
12/26/2014 227.82 3327016
12/24/2014 222.26 1333518
12/23/2014 220.97 4513321
12/22/2014 222.6 4806917
12/19/2014 219.29 6910461
12/18/2014 218.26 7483349
12/17/2014 205.82 7367834
12/16/2014 197.81 8426105
12/15/2014 204.04 5218252
12/12/2014 207 7173782
而这个数据实际上涵盖了两年-2013-14。如果我想按年份分组,那么对于2013和2014,我该如何,例如:
proc means data=tsla;
// something here to break out Date by 2013 and 2014?
run;
给出:
有没有办法告诉 SAS 按年(日期)或类似的语法将其分解?
类似于:
proc univariate data=tsla;
var Close Volume;
run;
SAS 的一个优点是它在使用汇总过程时按格式化值分组。这意味着如果您将日期字段格式化为年份,它将按年份分组,而无需创建额外的列。
data have;
input Date : mmddyy10. Close Volume;
format date mmddyy10.;
datalines;
12/31/2014 222.41 2402097
12/30/2014 222.23 2903242
12/29/2014 225.71 2811828
12/26/2014 227.82 3327016
12/24/2014 222.26 1333518
12/23/2014 220.97 4513321
12/22/2014 222.6 4806917
12/19/2014 219.29 6910461
12/18/2014 218.26 7483349
12/17/2014 205.82 7367834
12/16/2014 197.81 8426105
12/15/2014 204.04 5218252
12/12/2014 207 7173782
;
run;
proc means data=have sum mean;
class date;
format date year.;
var close volume;
run;
由于您似乎需要更明确的细节,我将在此处解释一些有帮助的主要概念。
首先,SAS 有两种基本类型:数字和字符。它有一些派生类型,它们不是真正的类型——它们是解释数字的方式。 Date 是其中一种派生类型。日期值作为自 1/1/1960 以来的天数存储在数字字段中;所以今天是 20117。
SAS 然后使用 formats 将该基础数字转换为视觉上有用的东西。 Excel 的工作方式完全相同,只是开始日期不同(Excel 为 1/1/1900),因此这通常有助于解释。 SAS 的格式是 Excel 的数字格式,除了功能更强大之外,完全相同的想法。
这些格式总是以字符开头,然后以句点或句点后跟数字结尾。例如,mmddyy10.
是 mmddyyw. 格式,其中 w.d
表示 width.decimal
(宽度 = 显示的字符总数,小数点 = 小数点后的位数) , 除了 mmddyyw.
由于显而易见的原因没有小数。
SAS 也有 informats
,它们与格式类似,只是相反:"How do I store this textual value as a number?"。因此,如果 MMDDYYw.
格式将 20117
转换为 01/29/2015
,则 MMDDYYw.
格式会将 01/29/2015
转换为 20117
。如果您想利用 SAS 的格式化功能,则必须进行转换:SAS 无法使用 01/29/2015
并弄清楚如何将其显示为 2015-01-29
,但它可以将其转换为 20117,然后显示 那 任意数量的方式。
那么,Keith 在他的回答中所做的,以及我同意的一个很好的解决方案(以及我会做的),是使用 mmddyy10.
信息格式将 01/29/2015
转换为 20117
,然后使用 YEAR4.
格式(YEARw.
,其中 w=4
)将 2014 年的任何日期显示为 2014
,以及 2013 年的任何日期作为 2013
。这是一种技巧,但它是一个很好的技巧:它不需要创建新变量,并且日期仍然具有它们过去使用的所有信息 - 它们只是在屏幕上显示为 2014
。
他正在做的另一件事是利用 proc means
(和大多数触发)的工作方式。如果它们具有 summarizing/grouping 功能,则该功能基于分组依据的字段的 格式化 值起作用。对于 proc means
,主要的分组方法是 class
- 它基本上表示在 SQL 中“按每个唯一的 class 变量值. Works nearly identically to
分组”。所以:
proc means data=<yourdata>;
class date;
var close volume;
run;
将为 date
的每个唯一值汇总 close
和 volume
。除了这里,这意味着它将每天分别汇总 - 这没有用!
proc means data=<yourdata>;
class date;
var close volume;
format date YEAR4.;
run;
啊哈。现在,日期由 year
的格式化值汇总。所以你的输出将类似于
Date close volume
2013 15.34 123135342
2014 16.13 151232144
(除了多一点,因为您不仅得到一个平均值,而且还有 n 和 stdev 以及 max/min)。
这在功能上类似于添加 year
列,这可能更容易理解。假设您有一个包含此数据的数据集 have
。
data for_means;
set have;
year = year(date);
run;
这将在新列 year
中存储日期的年份(假设它存储为 SAS 日期,一个数字)。那么你可以这样做:
proc means data=for_means;
class year;
var close volume;
run;
但是 Keith 的方法 - 使用格式 - 更容易和更快。
我知道那些关注 SAS 标签的人已经习惯了这个论坛上一些非常高级的东西。我现在只是想学习我的基础知识,并根据我使用 SQL 或只是 Excel 的经验来思考。我想知道如何按日期列的年份部分进行分组。我做了一些 Google 搜索并迷路了。
如果我有这样的样本数据集:
Date Close Volume
12/31/2014 222.41 2402097
12/30/2014 222.23 2903242
12/29/2014 225.71 2811828
12/26/2014 227.82 3327016
12/24/2014 222.26 1333518
12/23/2014 220.97 4513321
12/22/2014 222.6 4806917
12/19/2014 219.29 6910461
12/18/2014 218.26 7483349
12/17/2014 205.82 7367834
12/16/2014 197.81 8426105
12/15/2014 204.04 5218252
12/12/2014 207 7173782
而这个数据实际上涵盖了两年-2013-14。如果我想按年份分组,那么对于2013和2014,我该如何,例如:
proc means data=tsla;
// something here to break out Date by 2013 and 2014?
run;
给出:
有没有办法告诉 SAS 按年(日期)或类似的语法将其分解?
类似于:
proc univariate data=tsla;
var Close Volume;
run;
SAS 的一个优点是它在使用汇总过程时按格式化值分组。这意味着如果您将日期字段格式化为年份,它将按年份分组,而无需创建额外的列。
data have;
input Date : mmddyy10. Close Volume;
format date mmddyy10.;
datalines;
12/31/2014 222.41 2402097
12/30/2014 222.23 2903242
12/29/2014 225.71 2811828
12/26/2014 227.82 3327016
12/24/2014 222.26 1333518
12/23/2014 220.97 4513321
12/22/2014 222.6 4806917
12/19/2014 219.29 6910461
12/18/2014 218.26 7483349
12/17/2014 205.82 7367834
12/16/2014 197.81 8426105
12/15/2014 204.04 5218252
12/12/2014 207 7173782
;
run;
proc means data=have sum mean;
class date;
format date year.;
var close volume;
run;
由于您似乎需要更明确的细节,我将在此处解释一些有帮助的主要概念。
首先,SAS 有两种基本类型:数字和字符。它有一些派生类型,它们不是真正的类型——它们是解释数字的方式。 Date 是其中一种派生类型。日期值作为自 1/1/1960 以来的天数存储在数字字段中;所以今天是 20117。
SAS 然后使用 formats 将该基础数字转换为视觉上有用的东西。 Excel 的工作方式完全相同,只是开始日期不同(Excel 为 1/1/1900),因此这通常有助于解释。 SAS 的格式是 Excel 的数字格式,除了功能更强大之外,完全相同的想法。
这些格式总是以字符开头,然后以句点或句点后跟数字结尾。例如,mmddyy10.
是 mmddyyw. 格式,其中 w.d
表示 width.decimal
(宽度 = 显示的字符总数,小数点 = 小数点后的位数) , 除了 mmddyyw.
由于显而易见的原因没有小数。
SAS 也有 informats
,它们与格式类似,只是相反:"How do I store this textual value as a number?"。因此,如果 MMDDYYw.
格式将 20117
转换为 01/29/2015
,则 MMDDYYw.
格式会将 01/29/2015
转换为 20117
。如果您想利用 SAS 的格式化功能,则必须进行转换:SAS 无法使用 01/29/2015
并弄清楚如何将其显示为 2015-01-29
,但它可以将其转换为 20117,然后显示 那 任意数量的方式。
那么,Keith 在他的回答中所做的,以及我同意的一个很好的解决方案(以及我会做的),是使用 mmddyy10.
信息格式将 01/29/2015
转换为 20117
,然后使用 YEAR4.
格式(YEARw.
,其中 w=4
)将 2014 年的任何日期显示为 2014
,以及 2013 年的任何日期作为 2013
。这是一种技巧,但它是一个很好的技巧:它不需要创建新变量,并且日期仍然具有它们过去使用的所有信息 - 它们只是在屏幕上显示为 2014
。
他正在做的另一件事是利用 proc means
(和大多数触发)的工作方式。如果它们具有 summarizing/grouping 功能,则该功能基于分组依据的字段的 格式化 值起作用。对于 proc means
,主要的分组方法是 class
- 它基本上表示在 SQL 中“按每个唯一的 class 变量值. Works nearly identically to
分组”。所以:
proc means data=<yourdata>;
class date;
var close volume;
run;
将为 date
的每个唯一值汇总 close
和 volume
。除了这里,这意味着它将每天分别汇总 - 这没有用!
proc means data=<yourdata>;
class date;
var close volume;
format date YEAR4.;
run;
啊哈。现在,日期由 year
的格式化值汇总。所以你的输出将类似于
Date close volume
2013 15.34 123135342
2014 16.13 151232144
(除了多一点,因为您不仅得到一个平均值,而且还有 n 和 stdev 以及 max/min)。
这在功能上类似于添加 year
列,这可能更容易理解。假设您有一个包含此数据的数据集 have
。
data for_means;
set have;
year = year(date);
run;
这将在新列 year
中存储日期的年份(假设它存储为 SAS 日期,一个数字)。那么你可以这样做:
proc means data=for_means;
class year;
var close volume;
run;
但是 Keith 的方法 - 使用格式 - 更容易和更快。