Google 工作表合并和分组依据(自定义时间间隔)
Google sheets binning and group by (custom time interval)
我希望统计自定义时间间隔内发生的事件:可以是 24 小时内,也可以是一周或 2 个月内。
我正在使用 google 工作表:我可以创建一个数据透视表 table 并按月分组,但是我想使用自定义间隔来探索见解(我正在寻找癫痫症的模式).
作为最终结果,我想要一个 table,每天报告该间隔内的频率数。
特别是,我想关注 24 小时的间隔来计算癫痫事件的数量(称为丛集性发作)。
然后,在自定义天数间隔内探索周期性或趋势 - 例如每 48 小时,或每 15 或 30 天。
在此处查看 Google Sheet 的模型:
我试过这个尝试:
- 找出在报告日期之前的最后 30 天内发生了多少事件:
= IFERROR(
QUERY(
A:E,
"SELECT COUNT(A)
WHERE
A IS NOT NULL AND
E = FALSE AND
A >= date '" &
TEXT(
A2-30,
"yyyy-MM-dd"
) &"' AND
A <= date '" &
TEXT(
A2,
"yyyy-MM-dd"
) &"'
LABEL COUNT(A) '' "), "N/A")
然后,拖动单元格,我会看到“前 30 天的# 个事件”列。
它可以工作,但看起来有点乱 - 特别是对于更新间隔。
- 我尝试了另一种方法:
=query(B:E, "select B, count(E), -1+count(E) where E = FALSE group by B label B 'Date with Clusters', count(E) 'Cluster seizures '")
产生最后一个table。
我更喜欢这种方法,但这里我只是按同一日期分组,不可能有自定义间隔。
例如,我将计算同一天的两个事件,而不是相同的 24 小时间隔。
您能说出一种更好的方法来处理日期时间差异,以便使用自定义间隔创建装箱和分组吗?
下面举个例子:
左边table,输入数据;在中间栏,第一种方法的结果;右侧 table,第二种方法的结果。
鉴于 table:
为了使用 QUERY 对内容进行分组,我们需要“修复”A 列以获得自定义时间段。假设我们需要每 3 周(21 天)对事件进行一次分组。我们采用最低和最高日期并创建一个包含所有日期之间的序列。
=INDEX(ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A))))
然后我们使用 运行 total 得到每个日期,即与 previous/next 相隔 21 天的日期。我们可以使用简单的 SEQUENCE(对于 min>max)来创建这个数组,但是对于 SEQUENCE 我们不能“回到过去”(对于 max>min)所以我们使用 MMULT 和负数
因此,要从第一个日期的帧开始并按 windows(例如最小>最大)创建 3 周组,我们使用:
=ARRAYFORMULA({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
并从结束日期的框架开始并向后创建 3 周 windows(例如最大>最小),我们使用:
=ARRAYFORMULA({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
在这个阶段,我们可以开始通过 VLOOKUP 修复 A 列,并将第 4 个参数设置为 1
- 近似模式(而不是 0
- 精确匹配模式),以便及时向前:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
时间向后应为:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
现在我们只需创建一个虚拟数组 {}
并将固定列 A 与列 C 配对并将其作为范围输入到 QUERY
side note:
to put columns next to each other in english spreadsheets we use ,
to put columns next to each other in non-english spreadsheets we use \
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))
时间倒退:
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))
demo spreadsheet
我希望统计自定义时间间隔内发生的事件:可以是 24 小时内,也可以是一周或 2 个月内。
我正在使用 google 工作表:我可以创建一个数据透视表 table 并按月分组,但是我想使用自定义间隔来探索见解(我正在寻找癫痫症的模式).
作为最终结果,我想要一个 table,每天报告该间隔内的频率数。
特别是,我想关注 24 小时的间隔来计算癫痫事件的数量(称为丛集性发作)。
然后,在自定义天数间隔内探索周期性或趋势 - 例如每 48 小时,或每 15 或 30 天。
在此处查看 Google Sheet 的模型:
我试过这个尝试:
- 找出在报告日期之前的最后 30 天内发生了多少事件:
= IFERROR(
QUERY(
A:E,
"SELECT COUNT(A)
WHERE
A IS NOT NULL AND
E = FALSE AND
A >= date '" &
TEXT(
A2-30,
"yyyy-MM-dd"
) &"' AND
A <= date '" &
TEXT(
A2,
"yyyy-MM-dd"
) &"'
LABEL COUNT(A) '' "), "N/A")
然后,拖动单元格,我会看到“前 30 天的# 个事件”列。
它可以工作,但看起来有点乱 - 特别是对于更新间隔。
- 我尝试了另一种方法:
=query(B:E, "select B, count(E), -1+count(E) where E = FALSE group by B label B 'Date with Clusters', count(E) 'Cluster seizures '")
产生最后一个table。
我更喜欢这种方法,但这里我只是按同一日期分组,不可能有自定义间隔。
例如,我将计算同一天的两个事件,而不是相同的 24 小时间隔。
您能说出一种更好的方法来处理日期时间差异,以便使用自定义间隔创建装箱和分组吗?
下面举个例子: 左边table,输入数据;在中间栏,第一种方法的结果;右侧 table,第二种方法的结果。
鉴于 table:
为了使用 QUERY 对内容进行分组,我们需要“修复”A 列以获得自定义时间段。假设我们需要每 3 周(21 天)对事件进行一次分组。我们采用最低和最高日期并创建一个包含所有日期之间的序列。
=INDEX(ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A))))
然后我们使用 运行 total 得到每个日期,即与 previous/next 相隔 21 天的日期。我们可以使用简单的 SEQUENCE(对于 min>max)来创建这个数组,但是对于 SEQUENCE 我们不能“回到过去”(对于 max>min)所以我们使用 MMULT 和负数
因此,要从第一个日期的帧开始并按 windows(例如最小>最大)创建 3 周组,我们使用:
=ARRAYFORMULA({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
并从结束日期的框架开始并向后创建 3 周 windows(例如最大>最小),我们使用:
=ARRAYFORMULA({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
在这个阶段,我们可以开始通过 VLOOKUP 修复 A 列,并将第 4 个参数设置为 1
- 近似模式(而不是 0
- 精确匹配模式),以便及时向前:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
时间向后应为:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
现在我们只需创建一个虚拟数组 {}
并将固定列 A 与列 C 配对并将其作为范围输入到 QUERY
side note:
to put columns next to each other in english spreadsheets we use
,
to put columns next to each other in non-english spreadsheets we use
\
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))
时间倒退:
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))