首页 > 解决方案 > 仅当另一个选定列符合条件时,如何比较两个单独列的日期

问题描述

只是想知道是否有人可以帮助我解决这个令人沮丧的问题——我不知道该怎么做,因为它涉及到一系列问题。我对编码很陌生,所以这个问题可能有一些不清楚的地方——如果有什么不明白的地方请告诉我!

我的数据示例

#reproducible data (hopefully)

dat <-structure(list(id = 1:5, 
                     opstart = structure(c(1514970000, 1514904000, 1514916900, 1514883900, 1514979600), 
                                         class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                     crdate_1 = structure(c(1514818380, 1514965080,1514752680, 1514760180, 1514919480), 
                                          class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                      crdate_2 = structure(c(1515058680, 1515058740,1514817780, 1514965080, 1515064560), 
                                          class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                     crdate_3 = structure(c(1515564000, 1515137700,  1514876100, NA, 1516101000), 
                                          class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                      aki_1 = c("aki", NA, NA, NA, "aki"),
                      aki_2 = c("aki", NA, "aki", NA, "aki"), 
                     aki_3 = c("aki", "aki", "aki", NA, "aki")), 
                    row.names = c(NA, 5L), class = "data.frame")
id             opstart            crdate_1            crdate_2            crdate_3 aki_1 aki_2 aki_3
1  1 2018-01-03 09:00:00 2018-01-01 14:53:00 2018-01-04 09:38:00 2018-01-10 06:00:00   aki   aki   aki
2  2 2018-01-02 14:40:00 2018-01-03 07:38:00 2018-01-04 09:39:00 2018-01-05 07:35:00  <NA>  <NA>   aki
3  3 2018-01-02 18:15:00 2017-12-31 20:38:00 2018-01-01 14:43:00 2018-01-02 06:55:00  <NA>   aki   aki
4  4 2018-01-02 09:05:00 2017-12-31 22:43:00 2018-01-03 07:38:00                <NA>  <NA>  <NA>  <NA>
5  5 2018-01-03 11:40:00 2018-01-02 18:58:00 2018-01-04 11:16:00 2018-01-16 11:10:00   aki   aki   aki

我要做的是使用 mutate 创建一个名为 aki_status 的新列,该列将详细说明“aki”是在 opdate 之前还是在 opdate 之后。crdate_1 对应 aki_1,crdate_2 对应 aki_2 等等。

复杂之处在于 aki_status 应该基于“aki”首先出现的列。例如,对于第一行,aki 出现在 aki_1 中,因此 crdate_1 将用于与 opdate 的比较,但在第三行,aki 首先出现在 aki_2 中,因此应在与 opdate 的比较中使用 crdate_2。

理想的输出是

aki_status(preop, postop, preop, NA, postop)

标签: r

解决方案


这是一种依赖于首先将原始数据重塑为更易于使用的更长格式的方法。此处的“spec”表定义了我们希望源数据中的列输入到哪个列(“date、“aki”或“obs”)。

library(tidyverse)
spec <- tribble(
  ~.name,    ~.value, ~obs,
  "crdate_1", "date", 1,
  "crdate_2", "date", 2,
  "crdate_3", "date", 3,
  "aki_1",    "aki",  1,
  "aki_2",    "aki",  2,
  "aki_3",    "aki",  3
)

dat_long <- pivot_longer_spec(dat, spec) 

该表更易于使用,因为它允许我们直接将每个 crdate 与其各自的 opstart 日期进行比较,同时跟踪它是哪一轮。

#> dat_long
## A tibble: 15 x 5
#      id opstart               obs date                aki  
#   <int> <dttm>              <dbl> <dttm>              <chr>
# 1     1 2018-01-03 09:00:00     1 2018-01-01 14:53:00 aki  
# 2     1 2018-01-03 09:00:00     2 2018-01-04 09:38:00 aki  
# 3     1 2018-01-03 09:00:00     3 2018-01-10 06:00:00 aki  
# 4     2 2018-01-02 14:40:00     1 2018-01-03 07:38:00 NA   
# 5     2 2018-01-02 14:40:00     2 2018-01-04 09:39:00 NA   
# 6     2 2018-01-02 14:40:00     3 2018-01-05 07:35:00 aki  
# 7     3 2018-01-02 18:15:00     1 2017-12-31 20:38:00 NA   
# 8     3 2018-01-02 18:15:00     2 2018-01-01 14:43:00 aki  
# 9     3 2018-01-02 18:15:00     3 2018-01-02 06:55:00 aki  
#10     4 2018-01-02 09:05:00     1 2017-12-31 22:43:00 NA   
#11     4 2018-01-02 09:05:00     2 2018-01-03 07:38:00 NA   
#12     4 2018-01-02 09:05:00     3 NA                  NA   
#13     5 2018-01-03 11:40:00     1 2018-01-02 18:58:00 aki  
#14     5 2018-01-03 11:40:00     2 2018-01-04 11:16:00 aki  
#15     5 2018-01-03 11:40:00     3 2018-01-16 11:10:00 aki  

现在我们可以查看每个“id”中的第一个“aki”,以获得每个“id”的摘要统计信息“aki_status”。

results <- dat_long %>%
  group_by(id) %>%
  filter(aki == "aki") %>%
  slice_min(date) %>%  # or slice_min(obs) -- same result always?
  mutate(aki_status = if_else(date < opstart, "preop", "postop"))

dat %>% left_join(results, by = c("id", "opstart"))

  id             opstart            crdate_1            crdate_2            crdate_3 aki_1 aki_2 aki_3 obs                date  aki aki_status
1  1 2018-01-03 09:00:00 2018-01-01 14:53:00 2018-01-04 09:38:00 2018-01-10 06:00:00   aki   aki   aki   1 2018-01-01 14:53:00  aki      preop
2  2 2018-01-02 14:40:00 2018-01-03 07:38:00 2018-01-04 09:39:00 2018-01-05 07:35:00  <NA>  <NA>   aki   3 2018-01-05 07:35:00  aki     postop
3  3 2018-01-02 18:15:00 2017-12-31 20:38:00 2018-01-01 14:43:00 2018-01-02 06:55:00  <NA>   aki   aki   2 2018-01-01 14:43:00  aki      preop
4  4 2018-01-02 09:05:00 2017-12-31 22:43:00 2018-01-03 07:38:00                <NA>  <NA>  <NA>  <NA>  NA                <NA> <NA>       <NA>
5  5 2018-01-03 11:40:00 2018-01-02 18:58:00 2018-01-04 11:16:00 2018-01-16 11:10:00   aki   aki   aki   1 2018-01-02 18:58:00  aki      preop

推荐阅读