我有一个来自调查的数据集,第一列包含 ID,第二列包含格式为 yyyymmdd 的采访日期,范围从 2021 年 1 月 1 日到 2021 年 2 月 28 日。此外,温度数据分布在 59 列中,每列标记为 Xyyyymmdd,代表一月和二月的每一天。
现在,我需要计算每个人在过去 7 天内温度超过 30 摄氏度的总天数。值得注意的是,由于我的数据集中缺乏该时期的数据,因此今年的前 7 天不会有任何温度测量结果。
面试日期不连续,但温度列按日期顺序排列。
下面给出示例以了解数据的结构:
身份证 | 面试日期 | X20210101 | X20210102 | X20210103 |
---|---|---|---|---|
1 | 20210101 | 25 | 31 | 35 |
2 | 20210102 | 24 | 26 | 31 |
3 | 20210201 | 24 | 26 | 31 |
4 | 20210202 | 26 | 21 | 31 |
我正在使用 R。
首先在面试日期前往
"Date"
课程。
> dat$Interview_date <- as.Date(dat$Interview_date, '%Y%m%d')
接下来,制作“X”日期的向量,
> xdates <- as.Date(names(dat)[-(1:2)], 'X%Y%m%d')
将超过 30° 的温度矩阵乘以时间范围内的
xdates
[Interview_date, Interview_date - 7d] 并取 rowSums
。
> dat$exceed_30 <- ((dat[-(1:2)] >= 30)*
+ t(mapply(\(x, y) x <= y & x >= y - 7, list(xdates), dat$Interview_date))) |>
+ rowSums()
> dat
ID Interview_date X20210101 X20210102 X20210103 X20210104 exceed_30
1 1.0 2021-01-01 25 31 35 29 0
2 2.0 2021-01-02 29 30 31 29 1
3 2.1 2021-01-04 29 31 31 29 2
4 3.0 2021-02-01 24 26 31 29 0
5 4.0 2021-02-02 26 21 31 29 0
数据:
> dput(dat)
structure(list(ID = c(1, 2, 2.1, 3, 4), Interview_date = c("20210101",
"20210102", "20210104", "20210201", "20210202"), X20210101 = c(25L,
29L, 29L, 24L, 26L), X20210102 = c(31L, 30L, 31L, 26L, 21L),
X20210103 = c(35L, 31L, 31L, 31L, 31L), X20210104 = c(29L,
29L, 29L, 29L, 29L)), row.names = c(NA, -5L), class = "data.frame")
转为长整型,转换为日期,然后对面试日期后 0-7 天内大于 30 度的行进行求和。
library(tidyr)
library(dplyr)
library(lubridate)
dat %>%
pivot_longer(X20210101:X20210103, names_to = "Date", values_to = "Temp", names_prefix = "X") %>%
mutate(across(`Interview date`:Date, ymd)) %>%
summarize(
HotDays = sum(Temp > 30 & `Interview date` - Date <= 7 & `Interview date` >= Date),
.by = ID
)
# note, OP’s example data doesn’t include any dates meeting criteria
# # A tibble: 4 × 2
# ID HotDays
# <dbl> <int>
# 1 1 0
# 2 2 0
# 3 3 0
# 4 4 0