如何找到一列中的值与多列中的值的最小差异
how to find the min difference from a value in one col to the value from multiple cols
我有一个如下所示的 df。我想找到在 date
之前发生的最近日期 (from R_1:R_10)
。是不是可以一次计算R1:R10
到date
的天数差,然后挑出我们想要的值,然后把它放在一个新的变量cdate
中?
输出将如下所示:
cdate
将由 R_1:R10-date 标识,负值最大的那个将是我们输入 cdate
的日期
示例数据:
df<-structure(list(id = c("A0003", "A0003", "A0003", "A0003", "A0003",
"A0003", "A0005", "A0005"), date = structure(c(17774, 17799,
17805, 17837, 17846, 17873, 17784, 17784), class = "Date"), R_1 = structure(c(17773,
17773, 17773, 17773, 17773, 17773, 17785, 17785), class = "Date"),
R_2 = structure(c(17815, 17815, 17815, 17815, 17815, 17815,
17827, 17827), class = "Date"), R_5 = structure(c(17794,
17794, 17794, 17794, 17794, 17794, 17806, 17806), class = "Date"),
R_10 = structure(c(17871, 17871, 17871, 17871, 17871, 17871,
NA, NA), class = "Date")), row.names = c(NA, 8L), class = "data.frame")
我们可以将数据加入汇总版本,通过将数据旋转更长的时间,按 id 和日期分组,过滤掉 R_x 较晚的日期,并对最后一个进行汇总。
library(dplyr)
df %>%
left_join(
df %>%
tidyr::pivot_longer(-c(id,date)) %>%
group_by(id, date) %>%
filter(value <= date) %>%
summarize(cdate = max(value), .groups = "drop")
)
结果
Joining, by = c("id", "date")
id date R_1 R_2 R_5 R_10 cdate
1 A0003 2018-08-31 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-08-30
2 A0003 2018-09-25 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
3 A0003 2018-10-01 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
4 A0003 2018-11-02 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
5 A0003 2018-11-11 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
6 A0003 2018-12-08 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-12-06
7 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
8 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
使用base R
,我们用lapply
、replace
遍历'R_'列大于'date'到[=15=的值],然后使用 pmax
到 return max
日期值
df$cdate <- do.call(pmax, c(lapply(df[grep("R_", names(df))],
\(x) replace(x, x > df$date, NA)), na.rm = TRUE))
-输出
> df
id date R_1 R_2 R_5 R_10 cdate
1 A0003 2018-08-31 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-08-30
2 A0003 2018-09-25 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
3 A0003 2018-10-01 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
4 A0003 2018-11-02 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
5 A0003 2018-11-11 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
6 A0003 2018-12-08 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-12-06
7 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
8 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
我有一个如下所示的 df。我想找到在 date
之前发生的最近日期 (from R_1:R_10)
。是不是可以一次计算R1:R10
到date
的天数差,然后挑出我们想要的值,然后把它放在一个新的变量cdate
中?
输出将如下所示:
cdate
将由 R_1:R10-date 标识,负值最大的那个将是我们输入 cdate
示例数据:
df<-structure(list(id = c("A0003", "A0003", "A0003", "A0003", "A0003",
"A0003", "A0005", "A0005"), date = structure(c(17774, 17799,
17805, 17837, 17846, 17873, 17784, 17784), class = "Date"), R_1 = structure(c(17773,
17773, 17773, 17773, 17773, 17773, 17785, 17785), class = "Date"),
R_2 = structure(c(17815, 17815, 17815, 17815, 17815, 17815,
17827, 17827), class = "Date"), R_5 = structure(c(17794,
17794, 17794, 17794, 17794, 17794, 17806, 17806), class = "Date"),
R_10 = structure(c(17871, 17871, 17871, 17871, 17871, 17871,
NA, NA), class = "Date")), row.names = c(NA, 8L), class = "data.frame")
我们可以将数据加入汇总版本,通过将数据旋转更长的时间,按 id 和日期分组,过滤掉 R_x 较晚的日期,并对最后一个进行汇总。
library(dplyr)
df %>%
left_join(
df %>%
tidyr::pivot_longer(-c(id,date)) %>%
group_by(id, date) %>%
filter(value <= date) %>%
summarize(cdate = max(value), .groups = "drop")
)
结果
Joining, by = c("id", "date")
id date R_1 R_2 R_5 R_10 cdate
1 A0003 2018-08-31 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-08-30
2 A0003 2018-09-25 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
3 A0003 2018-10-01 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
4 A0003 2018-11-02 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
5 A0003 2018-11-11 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
6 A0003 2018-12-08 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-12-06
7 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
8 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
使用base R
,我们用lapply
、replace
遍历'R_'列大于'date'到[=15=的值],然后使用 pmax
到 return max
日期值
df$cdate <- do.call(pmax, c(lapply(df[grep("R_", names(df))],
\(x) replace(x, x > df$date, NA)), na.rm = TRUE))
-输出
> df
id date R_1 R_2 R_5 R_10 cdate
1 A0003 2018-08-31 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-08-30
2 A0003 2018-09-25 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
3 A0003 2018-10-01 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-09-20
4 A0003 2018-11-02 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
5 A0003 2018-11-11 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-10-11
6 A0003 2018-12-08 2018-08-30 2018-10-11 2018-09-20 2018-12-06 2018-12-06
7 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>
8 A0005 2018-09-10 2018-09-11 2018-10-23 2018-10-02 <NA> <NA>