根据前几天的数据(滞后变量)创建新的数据框列
Create new data frame column conditional on previous days data (lagged variable)
我正在处理一个温度数据集,我希望突出显示连续最高温度超过 30C 的天数,并在数据框中创建一个新的 TRUE/FALSE 列来突出显示热浪。为此,我需要查看前 3 天的数据并验证它们是否都满足此条件,以及当天本身。
我尝试使用 lag 命令为 -1 天、-2 天和 -3 天生成多个新列,然后使用 ifelse 语句验证所有列是否正确。但这似乎不是一种有效的做事方式,而且我似乎无法让滞后变量看起来过去。由于多个气象站记录每日数据,我还需要单独查看每个气象站以验证特定日期的热浪。
station_id = c(rep(1,10), rep(2,10))
date = c("20190129", "20190130", "20190131", "20190201", "20190202", "20190203", "20190204", "20190205", "20190206", "20190207")
max_temp = c(27, 35, 36, 38, 31, 32, 33, 29, 28, 26, 21, 20, 13, 31, 31, 32, 33, 35, 25, 20)
data = data.frame(station_id, date, max_temp)
print(data)
lag(data$max_temp, 3) #gives the forward lagging but i cant seem to be able to look backwards using negative numbers, perhaps I need to not include the first few columns?
我会使用 tidyverse
方法。您可以使用 dplyr::lag()
而不是使用 stats::lag()
,这对于您要完成的任务来说更直接一些:
library(tidyverse)
dfr <- dfr %>%
group_by(station_id) %>%
mutate(Heat_Wave = case_when(
max_temp >= 30 & lag(max_temp, 1) >= 30 & lag(max_temp, 2) >= 30 ~ TRUE, TRUE ~ FALSE
)) %>%
ungroup()
print(dfr)
station_id date max_temp Heat_Wave
1 1 20190129 27 FALSE
2 1 20190130 35 FALSE
3 1 20190131 36 FALSE
4 1 20190201 38 TRUE
5 1 20190202 31 TRUE
6 1 20190203 32 TRUE
7 1 20190204 33 TRUE
8 1 20190205 29 FALSE
9 1 20190206 28 FALSE
10 1 20190207 26 FALSE
11 2 20190129 21 FALSE
12 2 20190130 20 FALSE
13 2 20190131 13 FALSE
14 2 20190201 31 FALSE
15 2 20190202 31 FALSE
16 2 20190203 32 TRUE
17 2 20190204 33 TRUE
18 2 20190205 35 TRUE
19 2 20190206 25 FALSE
20 2 20190207 20 FALSE
我对 jon 的回答有一个小小的修正。您应该为每个站点 ID 使用 group_by(data,station_id)
从 tidyverse 到 运行 单独的函数 - 否则,结果将在站点之间溢出。这在你的例子中并不重要,但如果你的数据是这样的:
station_id date max_temp
1 20190204 15
1 20190205 30
1 20190206 30
1 20190207 30
2 20190129 30
这将是一个问题。您不希望最后一行 return TRUE。
所以新函数是:
data<-group_by(data,station_id)%>%
mutate(heatwave=case_when(
max_temp>=30 & lag(max_temp,1)>=30 & lag(max_temp,2)>=30 ~ TRUE, TRUE ~ FALSE))
事后别忘了ungroup()
,以免发生意外!
我正在处理一个温度数据集,我希望突出显示连续最高温度超过 30C 的天数,并在数据框中创建一个新的 TRUE/FALSE 列来突出显示热浪。为此,我需要查看前 3 天的数据并验证它们是否都满足此条件,以及当天本身。
我尝试使用 lag 命令为 -1 天、-2 天和 -3 天生成多个新列,然后使用 ifelse 语句验证所有列是否正确。但这似乎不是一种有效的做事方式,而且我似乎无法让滞后变量看起来过去。由于多个气象站记录每日数据,我还需要单独查看每个气象站以验证特定日期的热浪。
station_id = c(rep(1,10), rep(2,10))
date = c("20190129", "20190130", "20190131", "20190201", "20190202", "20190203", "20190204", "20190205", "20190206", "20190207")
max_temp = c(27, 35, 36, 38, 31, 32, 33, 29, 28, 26, 21, 20, 13, 31, 31, 32, 33, 35, 25, 20)
data = data.frame(station_id, date, max_temp)
print(data)
lag(data$max_temp, 3) #gives the forward lagging but i cant seem to be able to look backwards using negative numbers, perhaps I need to not include the first few columns?
我会使用 tidyverse
方法。您可以使用 dplyr::lag()
而不是使用 stats::lag()
,这对于您要完成的任务来说更直接一些:
library(tidyverse)
dfr <- dfr %>%
group_by(station_id) %>%
mutate(Heat_Wave = case_when(
max_temp >= 30 & lag(max_temp, 1) >= 30 & lag(max_temp, 2) >= 30 ~ TRUE, TRUE ~ FALSE
)) %>%
ungroup()
print(dfr)
station_id date max_temp Heat_Wave
1 1 20190129 27 FALSE
2 1 20190130 35 FALSE
3 1 20190131 36 FALSE
4 1 20190201 38 TRUE
5 1 20190202 31 TRUE
6 1 20190203 32 TRUE
7 1 20190204 33 TRUE
8 1 20190205 29 FALSE
9 1 20190206 28 FALSE
10 1 20190207 26 FALSE
11 2 20190129 21 FALSE
12 2 20190130 20 FALSE
13 2 20190131 13 FALSE
14 2 20190201 31 FALSE
15 2 20190202 31 FALSE
16 2 20190203 32 TRUE
17 2 20190204 33 TRUE
18 2 20190205 35 TRUE
19 2 20190206 25 FALSE
20 2 20190207 20 FALSE
我对 jon 的回答有一个小小的修正。您应该为每个站点 ID 使用 group_by(data,station_id)
从 tidyverse 到 运行 单独的函数 - 否则,结果将在站点之间溢出。这在你的例子中并不重要,但如果你的数据是这样的:
station_id date max_temp
1 20190204 15
1 20190205 30
1 20190206 30
1 20190207 30
2 20190129 30
这将是一个问题。您不希望最后一行 return TRUE。 所以新函数是:
data<-group_by(data,station_id)%>%
mutate(heatwave=case_when(
max_temp>=30 & lag(max_temp,1)>=30 & lag(max_temp,2)>=30 ~ TRUE, TRUE ~ FALSE))
事后别忘了ungroup()
,以免发生意外!