使用dplyr的mutate和case_何时测试多个列(日期间隔)

使用dplyr的mutate和case_何时测试多个列(日期间隔),r,dplyr,tidyverse,intervals,mutate,R,Dplyr,Tidyverse,Intervals,Mutate,我有一个数据集,大约250列对应于日期。我已经使用interval命令创建了一个时间间隔,我想测试250个日期列中的任何一个是否在%my interval变量内,并创建一个Y或N的新列 我尝试过但不奏效的方法大致如下: date_cols <- names(df[,1:250]) df_new <- df %>% mutate(test=case_when(date_cols %within% interval ~ "Y",

我有一个数据集,大约250列对应于日期。我已经使用interval命令创建了一个时间间隔,我想测试250个日期列中的任何一个是否在%my interval变量内,并创建一个Y或N的新列

我尝试过但不奏效的方法大致如下:

date_cols <- names(df[,1:250]) 

df_new <- df %>% 
  mutate(test=case_when(date_cols %within% interval ~ "Y",
                        TRUE ~ "N"))
如果我这样做的话,我希望它也能像我一样运作

df_new <- df %>%
mutate(test=case_when(date_col_1 %within% interval ~ "Y",
                     date_col_2 %within% interval ~ "Y",
                     ...
                     date_col_250 %within% interval ~ "Y",
                     TRUE ~ "N"))
显然,我不想在所有250列的行中键入case_,但我还没有找到或tidyverse或任何解决方案来尝试查找日期是否在间隔内


有什么想法吗?

< P>我认为在DPLYR中很难做到这一点,因为它实际上是BraseR中的一个内衬。让我们来看看你的设置的一个玩具版本,一个间隔和一个只有两个日期列的迷你数据帧:

联吡啶酯 间隔1 1 2020-06-30 2020-06-25 > 2 2 2020-07-01 2020-06-26 > 3 3 2020-07-02 2020-06-27 > 4 4 2020-07-03 2020-06-28 > 5 5 2020-07-04 2020-06-29 > 6 6 2020-07-05 2020-06-30 > 7 7 2020-07-06 2020-07-01 > 8 8 2020-07-07 2020-07-02 > 9 9 2020-07-08 2020-07-03 > 10 10 2020-07-09 2020-07-04 现在听起来好像您希望为每个现有的日期列指定一个逻辑列,指示其日期是否在间隔内。可以将这些列创建为新数据框,如下所示:

data.frame(t(apply(df[date_cols], 1, function(x) as.Date(x) %within% interval)))
#>       X1    X2
#> 1  FALSE FALSE
#> 2   TRUE FALSE
#> 3   TRUE FALSE
#> 4   TRUE FALSE
#> 5   TRUE FALSE
#> 6  FALSE FALSE
#> 7  FALSE  TRUE
#> 8  FALSE  TRUE
#> 9  FALSE  TRUE
#> 10 FALSE  TRUE
date_cols <- names(df[1:250])

df[date_cols] %>%
  apply(1, function(x) as.Date(x) %within% interval) %>%
  t() %>%
  data.frame() %>%
  setNames(paste0(date_cols, "_within_interval")) %>%
  cbind(df, .)
因此,如果要将列添加到数据框中,可以执行以下操作:

df2 <- data.frame(t(apply(df[date_cols], 1, function(x) as.Date(x) %within% interval)))
df2 <- setNames(df2, paste0(date_cols, "_in_interval"))

cbind(df, df2)
#>    id       col1       col2 col1_in_interval col2_in_interval
#> 1   1 2020-06-30 2020-06-25            FALSE            FALSE
#> 2   2 2020-07-01 2020-06-26             TRUE            FALSE
#> 3   3 2020-07-02 2020-06-27             TRUE            FALSE
#> 4   4 2020-07-03 2020-06-28             TRUE            FALSE
#> 5   5 2020-07-04 2020-06-29             TRUE            FALSE
#> 6   6 2020-07-05 2020-06-30            FALSE            FALSE
#> 7   7 2020-07-06 2020-07-01            FALSE             TRUE
#> 8   8 2020-07-07 2020-07-02            FALSE             TRUE
#> 9   9 2020-07-08 2020-07-03            FALSE             TRUE
#> 10 10 2020-07-09 2020-07-04            FALSE             TRUE
或者,使用管道,您的解决方案如下所示:

data.frame(t(apply(df[date_cols], 1, function(x) as.Date(x) %within% interval)))
#>       X1    X2
#> 1  FALSE FALSE
#> 2   TRUE FALSE
#> 3   TRUE FALSE
#> 4   TRUE FALSE
#> 5   TRUE FALSE
#> 6  FALSE FALSE
#> 7  FALSE  TRUE
#> 8  FALSE  TRUE
#> 9  FALSE  TRUE
#> 10 FALSE  TRUE
date_cols <- names(df[1:250])

df[date_cols] %>%
  apply(1, function(x) as.Date(x) %within% interval) %>%
  t() %>%
  data.frame() %>%
  setNames(paste0(date_cols, "_within_interval")) %>%
  cbind(df, .)
由v0.3.0于2020年7月2日创建,我们可以使用sapply over date_cols获取间隔内日期的真/假值。我们使用行和来确定是否有任何日期在间隔内

使用@Allan Cameron的数据:

library(lubridate)
date_cols <- 2:3
df$test <- rowSums(sapply(df[date_cols], `%within%`, interval)) > 0
df

#   id       col1       col2  test
#1   1 2020-06-30 2020-06-25 FALSE
#2   2 2020-07-01 2020-06-26  TRUE
#3   3 2020-07-02 2020-06-27  TRUE
#4   4 2020-07-03 2020-06-28  TRUE
#5   5 2020-07-04 2020-06-29  TRUE
#6   6 2020-07-05 2020-06-30 FALSE
#7   7 2020-07-06 2020-07-01  TRUE
#8   8 2020-07-07 2020-07-02  TRUE
#9   9 2020-07-08 2020-07-03  TRUE
#10 10 2020-07-09 2020-07-04  TRUE

马特,当我们有你的数据样本时,这真的很有帮助,如果样本显示出一点可变性更好。您能提供一份来自DPutheadedf的明确的数据样本吗?非常感谢!是否有一种方法可以代替为每个日期列创建多个逻辑列来创建一个单独的列,如果其中任何一个逻辑列为TRUE,则该列为TRUE,否则为FALSE?