【问题标题】:dplyr::between issue dplyr 1.0.7dplyr::在问题 dplyr 1.0.7 之间
【发布时间】:2026-01-19 15:30:01
【问题描述】:

我打开了一个旧脚本,下面对between 的使用不再有效。我之前提出的一个问题表明它曾经可以工作here。不幸的是,我不确定我当时使用的是什么版本。

library(lubridate)
library(tidyverse)
df <- data.frame(date1 = c("2011-09-18", "2013-03-06", "2013-08-08"),
                 date2 = c("2012-02-18", "2014-03-06", "2015-02-03"))
df$date1 <- as.Date(parse_date_time(df$date1, "ymd"))
df$date2 <- as.Date(parse_date_time(df$date2, "ymd"))
df
#        date1      date2
# 1 2011-09-18 2012-02-18
# 2 2013-03-06 2014-03-06
# 3 2013-08-08 2015-02-03

df$y_2014 <- if_else(between(2014, year(df$date1), year(df$date2)), 1, 0, as.numeric(NA))
#between(2014, year(df$date1), year(df$date2))

错误:left 的长度必须为 1

sessionInfo()
R version 4.0.3 (2020-10-10)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] forcats_0.5.0     stringr_1.4.0     dplyr_1.0.7       purrr_0.3.4       readr_1.4.0       tidyr_1.1.2      
 [7] tibble_3.0.5      ggplot2_3.3.3     tidyverse_1.3.0   lubridate_1.7.9.2

loaded via a namespace (and not attached):
 [1] tinytex_0.29     tidyselect_1.1.0 xfun_0.20        haven_2.3.1      colorspace_2.0-0 vctrs_0.3.8     
 [7] generics_0.1.0   htmltools_0.5.1  yaml_2.2.1       utf8_1.1.4       rlang_0.4.10     pillar_1.6.4    
[13] withr_2.4.0      glue_1.4.2       DBI_1.1.1        dbplyr_2.1.1     readxl_1.3.1     modelr_0.1.8    
[19] fortunes_1.5-4   lifecycle_1.0.1  cellranger_1.1.0 munsell_0.5.0    gtable_0.3.0     rvest_0.3.6     
[25] memoise_1.1.0    evaluate_0.14    knitr_1.30       ps_1.5.0         curl_4.3         fansi_0.4.2     
[31] urltools_1.7.3   triebeard_0.3.0  broom_0.7.3      Rcpp_1.0.7       scales_1.1.1     backports_1.2.1 
[37] jsonlite_1.7.2   fs_1.5.0         hms_1.0.0        pingr_2.0.1      digest_0.6.27    stringi_1.5.3   
[43] processx_3.4.5   cowplot_1.1.1    grid_4.0.3       rprojroot_2.0.2  cli_2.2.0        tools_4.0.3     
[49] magrittr_2.0.1   crayon_1.3.4     pkgconfig_2.0.3  ellipsis_0.3.2   xml2_1.3.2       reprex_0.3.0    
[55] datapasta_3.1.0  assertthat_0.2.1 rmarkdown_2.6    httr_1.4.2       rstudioapi_0.13  R6_2.5.0        
[61] speedtest_0.2.0  compiler_4.0.3

以前有人遇到过这个问题吗? 谢谢

【问题讨论】:

  • between() 以前从未打算为 leftright 向量化。您可以在dplyr changelog 中看到,在 1.0.3 中,between() 被澄清为不被矢量化。如果您查看relevant GitHub issue,您会发现他们添加了显式错误检查以确保向量不会传递给leftright,直到它们最终修改between() 以进行向量化。
  • 我一直对选择使其非矢量化感到失望。我通常加载data.tabledplyr,并且我通常显式屏蔽dplyr::between 来代替data.table::between,它 进行矢量化比较。不幸的是,您的最佳选择(缺少data.table::between)是year(df$date1) &lt;= 2014 &amp; 2014 &lt;= year(df$date2)
  • 感谢您提供有用的链接。 data.table::between 似乎完全符合我的要求

标签: r dplyr


【解决方案1】:

你可以使用 rowwise() 如果你不想加载 data.table 只是因为它之间:

library(lubridate)
library(tidyverse)

df %>% 
rowwise() %>% 
mutate(y_2014 = if_else(between(2014, year(date1), year(date2)), 1, 0, as.numeric(NA)))

# A tibble: 3 x 3
# Rowwise: 
  date1      date2      y_2014
  <date>     <date>      <dbl>
1 2011-09-18 2012-02-18      0
2 2013-03-06 2014-03-06      1
3 2013-08-08 2015-02-03      1

如果你想在你的数据表上进行一些其他的变异或转换或总结,可以使用 ungroup()

【讨论】:

  • 谢谢,我曾想过,但在这种情况下想避免它,因为它太慢了(大数据集)