r - 根据 .vars 外部的列转换多个列

标签 r dplyr

我有一个数据框,其中前 5 列是 bool 值,接下来的 2 列是开始日期和结束日期。 如果前 5 列等于 1,我想进行转换,以便为它们分配一个介于开始日期和结束日期之间的日期。 0 值可以保留为 0。

示例数据框:

df<- data.frame(A = c(1,1,0,0,1), B = c(0,1,0,0,1), C = c(0,0,1,1,0),D = c(1,0,0,0,1), E = c(1,1,1,0,0), 
                  StartDate = as.Date(c("2018-03-21","1999-02-06","2004-01-19", "2000-03-18", "1998-05-20")),
                  EndDate = as.Date(c("2020-08-02","2004-09-15","2009-07-27","2017-04-21", "2001-01-24"))

> A B C D E  StartDate    EndDate
  1 0 0 1 1 2018-03-21 2020-08-02
  1 1 0 0 1 1999-02-06 2004-09-15
  0 0 1 0 1 2004-01-19 2009-07-27
  0 0 1 0 0 2000-03-18 2017-04-21
  1 1 0 1 0 1998-05-20 2001-01-24

我想要一个输出,其中每个 1 值都替换为每行的 StartDate 和 EndDate 之间的随机日期,例如:

> A          B          C          D          E           StartDate    EndDate
  2019-07-22 0          0          2020-01-30 2018-03-26 2018-03-21 2020-08-02
  1999-03-21 2002-04-04 0          0          1999-09-14 1999-02-06 2004-09-15
  0          0          2005-06-07 0          2008-05-28 2004-01-19 2009-07-27
  0          0          2015-10-11 0          0          2000-03-18 2017-04-21
  1999-02-05 2000-11-14 0          1999-12-19 0          1998-05-20 2001-01-24

到目前为止,我的想法是:

对于 .vars = 1:5,运行 ifelse(),其中任何 1 值都会替换为 StartDate结束日期

df %>%
  transmute_at(.vars = 1:5,            
               .funs = ifelse(1,sample(seq(StartDate, EndDate, by = "day"), 1), 0) )

但是,这不会运行,因为它找不到 StartDateEndDate,因为代码仅针对 cols 1:5 运行

如有任何帮助,我们将不胜感激!

最佳答案

这里您需要考虑几个问题:

  • seq() 未对 fromto 进行矢量化,因此需要 StartDateEndDate 的长度为 1。您可以使用 rowwise()
  • 来实现此目的
  • 替换列的类型为 date,因此您将无法简单地包含零,因为这些将被强制转换为 1970-01-01(尝试 lubridate::as_date(0))。最好的选择可能是在这里使用 NA
  • transmute() 将删除正在使用的列,即它将删除 StartDateEndDate。如果你想保留它们,你应该使用 mutate() 代替
  • 示例中的主要问题是您的 .funs 参数不是函数。来自文档:

A function fun, a quosure style lambda ~ fun(.) or a list of either form.

  • 范围动词,即以 _at_if 等结尾的函数,从 {dplyr} 1.0 开始被 across() 取代。 0.

下面是一个考虑了上述因素的示例:

df %>% 
  rowwise() %>% 
  dplyr::mutate(
    across(1:5, ~lubridate::as_date(ifelse(
      . == 1, 
      sample(seq(StartDate, EndDate, by = "day"), 1), 
      NA
    )))
  ) %>% 
  ungroup()
#> # A tibble: 5 x 7
#>   A          B          C          D          E          StartDate  EndDate   
#>   <date>     <date>     <date>     <date>     <date>     <date>     <date>    
#> 1 2019-08-31 NA         NA         2019-09-30 2019-03-15 2018-03-21 2020-08-02
#> 2 2002-01-10 2001-11-25 NA         NA         2003-07-17 1999-02-06 2004-09-15
#> 3 NA         NA         2006-06-16 NA         2008-09-03 2004-01-19 2009-07-27
#> 4 NA         NA         2015-05-21 NA         NA         2000-03-18 2017-04-21
#> 5 1999-09-19 1999-08-30 NA         1999-11-04 NA         1998-05-20 2001-01-24

关于r - 根据 .vars 外部的列转换多个列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67676017/

相关文章:

r - 如何使用字符对象使用 dplyr 重命名 R 中的列?

r - 用于构建变量名称的 Dplyr Tidyyeval

r - 如何在排序的 x 和 y 轴值上使用 ggrepel 显示标签

以 tidyeval 的方式删除列

r - 如何改变rmarkdown中目录的位置?

java - 如何使用 Rserve 将文件路径传递给在 Java 中调用的 Rscript?

r - 使用聚合和过滤器进行高效的交叉连接

r - 如何在来自两个数据帧的分组值之间执行操作

r - 使用 R 对分组变量进行非线性优化

r - 如何在不自己修复日期的情况下获得日期无效的年份和月份?