以行方式用 *NA* 替换指定结束日期之后发生的所有日期
replace all dates that occur after a specified end date with an *NA* in a rowwise manner
我想用 NA[=20 替换列 "date_end" 中存储的指定结束日期之后发生的所有日期=] 以行的方式。
原始数据框:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
想要这样的数据框:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", NA, "2019-12-08"))
date4 <-as.Date(c("2019-07-31", NA, NA))
df_new <- data.frame(date_end, date1, date2, date3, date4)
这应该有效:
library(dplyr)
library(lubridate)
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
df %>%
rowwise() %>%
mutate(across(date1:date4, ~case_when(.x <= date_end ~ .x,
TRUE ~ NA_Date_)))
#> # A tibble: 3 × 5
#> # Rowwise:
#> date_end date1 date2 date3 date4
#> <date> <date> <date> <date> <date>
#> 1 2019-07-31 NA 2019-01-30 2019-03-19 2019-07-31
#> 2 2019-07-17 2019-05-01 2019-07-15 NA NA
#> 3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 NA
由 reprex package (v2.0.1)
创建于 2022-05-10
这也应该有效 - 只要第一行的 date1 应该是 NA,因为它在相应的结束日期之后:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
# create duplicate dataframe
df_new <- df
# use a loop to add NA to cells where the date is after the corresponding date_end
for (i in 1:nrow(df_new)) { # fo each row
for (j in 2:length(df_new)) { # for each column after date_end
if (df_new[i,1] < df_new[i,j]) { # if date in cell [i,j] is after end date of row i
df_new[i,j] <- NA # replace with NA
}
}
}
df_new
date_end date1 date2 date3 date4
1 2019-07-31 <NA> 2019-01-30 2019-03-19 2019-07-31
2 2019-07-17 2019-05-01 2019-07-15 <NA> <NA>
3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 <NA>
这是使用 sapply
:
的基础 R 解决方案
df[,-1][sapply(df[,-1], function(x) as.Date(x) > as.Date(df$date_end))] <- NA
输出
date_end date1 date2 date3 date4
1 2019-07-31 <NA> 2019-01-30 2019-03-19 2019-07-31
2 2019-07-17 2019-05-01 2019-07-15 <NA> <NA>
3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 <NA>
我想用 NA[=20 替换列 "date_end" 中存储的指定结束日期之后发生的所有日期=] 以行的方式。
原始数据框:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
想要这样的数据框:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", NA, "2019-12-08"))
date4 <-as.Date(c("2019-07-31", NA, NA))
df_new <- data.frame(date_end, date1, date2, date3, date4)
这应该有效:
library(dplyr)
library(lubridate)
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
df %>%
rowwise() %>%
mutate(across(date1:date4, ~case_when(.x <= date_end ~ .x,
TRUE ~ NA_Date_)))
#> # A tibble: 3 × 5
#> # Rowwise:
#> date_end date1 date2 date3 date4
#> <date> <date> <date> <date> <date>
#> 1 2019-07-31 NA 2019-01-30 2019-03-19 2019-07-31
#> 2 2019-07-17 2019-05-01 2019-07-15 NA NA
#> 3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 NA
由 reprex package (v2.0.1)
创建于 2022-05-10这也应该有效 - 只要第一行的 date1 应该是 NA,因为它在相应的结束日期之后:
date_end <-as.Date(c("2019-07-31", "2019-07-17", "2019-12-18"))
date1 <-as.Date(c("2019-10-31", "2019-05-01", "2019-07-27"))
date2 <-as.Date(c("2019-01-30", "2019-07-15", "2019-09-09"))
date3 <-as.Date(c("2019-03-19", "2020-01-15", "2019-12-08"))
date4 <-as.Date(c("2019-07-31", "2020-08-05", "2020-07-01"))
df <- data.frame(date_end, date1, date2, date3, date4)
# create duplicate dataframe
df_new <- df
# use a loop to add NA to cells where the date is after the corresponding date_end
for (i in 1:nrow(df_new)) { # fo each row
for (j in 2:length(df_new)) { # for each column after date_end
if (df_new[i,1] < df_new[i,j]) { # if date in cell [i,j] is after end date of row i
df_new[i,j] <- NA # replace with NA
}
}
}
df_new
date_end date1 date2 date3 date4
1 2019-07-31 <NA> 2019-01-30 2019-03-19 2019-07-31
2 2019-07-17 2019-05-01 2019-07-15 <NA> <NA>
3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 <NA>
这是使用 sapply
:
df[,-1][sapply(df[,-1], function(x) as.Date(x) > as.Date(df$date_end))] <- NA
输出
date_end date1 date2 date3 date4
1 2019-07-31 <NA> 2019-01-30 2019-03-19 2019-07-31
2 2019-07-17 2019-05-01 2019-07-15 <NA> <NA>
3 2019-12-18 2019-07-27 2019-09-09 2019-12-08 <NA>