确定最近的日期时间
identifying the most recent datetime
我在需要生成 df$val_most_recent
的逻辑方面遇到了一些问题。如果a_val
和b_val
都有值,那么val_most_recent
应该是最近一次的值(a_val
对应a_dtm
,b_val
对应b_dtm
)。如果时间相同,我希望 a_val
为 val_most_recent
。如果两者只报告一个值(另一个是 NA
,它应该只是那个值。
library(tidyverse)
library(lubridate)
location <- c("a", "b", "c", "d")
a_dtm <- ymd_hm(c(NA, "2019-06-05 10:30", "2019-06-05 10:45", "2019-06-05 10:50"))
b_dtm <- ymd_hm(c("2019-06-05 10:30", NA, "2019-06-05 10:48", "2019-06-05 10:50"))
a_val <- c(NA, 6, 4, 2)
b_val <- c(5, NA, 3, 2)
df <- data.frame(location, a_dtm, b_dtm, a_val, b_val)
as_tibble(df)
# A tibble: 4 x 5
#location a_dtm b_dtm a_val b_val
#<fct> <dttm> <dttm> <dbl> <dbl>
#1 a NA 2019-06-05 10:30:00 NA 5
#2 b 2019-06-05 10:30:00 NA 6 NA
#3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3
#4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2
val_most_recent <- c(5,6,3,2)
desired_df <- cbind(df, val_most_recent)
as_tibble(desired_df)
#location a_dtm b_dtm a_val b_val val_most_recent
#<fct> <dttm> <dttm> <dbl> <dbl> <dbl>
#1 a NA 2019-06-05 10:30:00 NA 5 5
#2 b 2019-06-05 10:30:00 NA 6 NA 6
#3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3 3
#4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2 2
这是 base R
中的一个选项,将日期转换为数字,将 NAs
替换为 0,获取每行中具有最大值的列索引,cbind
为行索引并从 'a_val/b_val' 列
中提取相应的值
m1 <- sapply(df[2:3], as.numeric)
df$val_most_recent <- df[4:5][cbind(seq_len(nrow(m1)),
max.col(replace(m1, is.na(m1), 0), "first"))]
df$val_most_recent
#[1] 5 6 3 2
这是您的文本中编码成 case_when
语句的逻辑:
df %>%
mutate(
val_most_recent = case_when(
is.na(a_val) | is.na(b_va) ~ coalesce(a_val, b_val),
a_dtm >= b_dtm ~ a_val,
TRUE ~ b_val
)
)
# location a_dtm b_dtm a_val b_val val_most_recent
# 1 a <NA> 2019-06-05 10:30:00 NA 5 5
# 2 b 2019-06-05 10:30:00 <NA> 6 NA 6
# 3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3 3
# 4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2 2
我在需要生成 df$val_most_recent
的逻辑方面遇到了一些问题。如果a_val
和b_val
都有值,那么val_most_recent
应该是最近一次的值(a_val
对应a_dtm
,b_val
对应b_dtm
)。如果时间相同,我希望 a_val
为 val_most_recent
。如果两者只报告一个值(另一个是 NA
,它应该只是那个值。
library(tidyverse)
library(lubridate)
location <- c("a", "b", "c", "d")
a_dtm <- ymd_hm(c(NA, "2019-06-05 10:30", "2019-06-05 10:45", "2019-06-05 10:50"))
b_dtm <- ymd_hm(c("2019-06-05 10:30", NA, "2019-06-05 10:48", "2019-06-05 10:50"))
a_val <- c(NA, 6, 4, 2)
b_val <- c(5, NA, 3, 2)
df <- data.frame(location, a_dtm, b_dtm, a_val, b_val)
as_tibble(df)
# A tibble: 4 x 5
#location a_dtm b_dtm a_val b_val
#<fct> <dttm> <dttm> <dbl> <dbl>
#1 a NA 2019-06-05 10:30:00 NA 5
#2 b 2019-06-05 10:30:00 NA 6 NA
#3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3
#4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2
val_most_recent <- c(5,6,3,2)
desired_df <- cbind(df, val_most_recent)
as_tibble(desired_df)
#location a_dtm b_dtm a_val b_val val_most_recent
#<fct> <dttm> <dttm> <dbl> <dbl> <dbl>
#1 a NA 2019-06-05 10:30:00 NA 5 5
#2 b 2019-06-05 10:30:00 NA 6 NA 6
#3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3 3
#4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2 2
这是 base R
中的一个选项,将日期转换为数字,将 NAs
替换为 0,获取每行中具有最大值的列索引,cbind
为行索引并从 'a_val/b_val' 列
m1 <- sapply(df[2:3], as.numeric)
df$val_most_recent <- df[4:5][cbind(seq_len(nrow(m1)),
max.col(replace(m1, is.na(m1), 0), "first"))]
df$val_most_recent
#[1] 5 6 3 2
这是您的文本中编码成 case_when
语句的逻辑:
df %>%
mutate(
val_most_recent = case_when(
is.na(a_val) | is.na(b_va) ~ coalesce(a_val, b_val),
a_dtm >= b_dtm ~ a_val,
TRUE ~ b_val
)
)
# location a_dtm b_dtm a_val b_val val_most_recent
# 1 a <NA> 2019-06-05 10:30:00 NA 5 5
# 2 b 2019-06-05 10:30:00 <NA> 6 NA 6
# 3 c 2019-06-05 10:45:00 2019-06-05 10:48:00 4 3 3
# 4 d 2019-06-05 10:50:00 2019-06-05 10:50:00 2 2 2