【问题标题】:Cannot filter column when name of that column comes from variable当列的名称来自变量时无法过滤列
【发布时间】:2020-08-06 10:28:33
【问题描述】:

默认情况下,我将参数 cut.points 设置为 NA,如果它是默认值,那么它不应该对数据做任何事情。

但是,如果用户决定输入例如cut.points = c("2012-01-01", "2013-01-01"),则数据应按其中包含日期的列进行过滤。它应该只返回 2012 年到 2013 年之间的日期。 问题是我正在从函数中读取数据,所以理论上我不知道使用提供的这个日期列的名称是什么。所以我找到带有日期的列并将其名称存储在变量中。

但是我写的应该基于这个变量过滤的条件不起作用:

modifier <- function(input.data, cut.points = c(NA, NA)) {
  date_check <- sapply(input.data, function(x) !all(is.na(as.Date(as.character(x),format="%Y-%m-%d"))))
  if (missing(cut.points)) {
    input.data
  } else {
    cols <- colnames(select_if(input.data, date_check == TRUE))
    cut.points <- as.Date(cut.points)
    input.data <- filter(input.data, cols > cut.points[1] & cols < cut.points[2])
  }
}

例如。当我尝试运行它时:

modifier(ex_data, cut.points = c("2012-01-01", "2013-01-01"))

在这样的示例上:

    ex_data
   Row.ID        Order.ID Order.Date
1   32298  CA-2012-124891 2012-07-31
2   26341   IN-2013-77878 2013-02-05
3   25330   IN-2013-71249 2013-10-17
4   13524 ES-2013-1579342 2013-01-28
5   47221    SG-2013-4320 2013-11-05
6   22732   IN-2013-42360 2013-06-28
7   30570   IN-2011-81826 2011-11-07
8   31192   IN-2012-86369 2012-04-14
9   40155  CA-2014-135909 2014-10-14
10  40936  CA-2012-116638 2012-01-28
11  34577  CA-2011-102988 2011-04-05
12  28879   ID-2012-28402 2012-04-19
13  45794    SA-2011-1830 2011-12-27
14   4132  MX-2012-130015 2012-11-13
15  27704   IN-2013-73951 2013-06-06
16  13779 ES-2014-5099955 2014-07-31
17  36178  CA-2014-143567 2014-11-03
18  12069 ES-2014-1651774 2014-09-08
19  22096   IN-2014-11763 2014-01-31
20  49463    TZ-2014-8190 2014-12-05

错误是: 字符串不是标准的明确格式

【问题讨论】:

  • 你能提供一个minimal reproducible example你的数据吗?
  • 是的,我已经编辑了问题
  • 如果您有多个日期列,如果其中一个列在 cut.points 内部而另一列在外部,那么一行应该发生什么?应该保留还是删除?
  • 我假设只有一列包含日期,如果这是您要问的内容

标签: r dataframe dplyr data-science


【解决方案1】:

我添加了 lubridate 作为依赖项,因此我可以访问 %within%is.Date。我还更改了检查条件,因为我认为您的原始条件不适用于NA, NA

library(tidyverse)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

ex_data <- read_table("   Row.ID        Order.ID Order.Date
1   32298  CA-2012-124891 2012-07-31
2   26341   IN-2013-77878 2013-02-05
3   25330   IN-2013-71249 2013-10-17
4   13524 ES-2013-1579342 2013-01-28
5   47221    SG-2013-4320 2013-11-05
6   22732   IN-2013-42360 2013-06-28
7   30570   IN-2011-81826 2011-11-07
8   31192   IN-2012-86369 2012-04-14
9   40155  CA-2014-135909 2014-10-14
10  40936  CA-2012-116638 2012-01-28
11  34577  CA-2011-102988 2011-04-05
12  28879   ID-2012-28402 2012-04-19
13  45794    SA-2011-1830 2011-12-27
14   4132  MX-2012-130015 2012-11-13
15  27704   IN-2013-73951 2013-06-06
16  13779 ES-2014-5099955 2014-07-31
17  36178  CA-2014-143567 2014-11-03
18  12069 ES-2014-1651774 2014-09-08
19  22096   IN-2014-11763 2014-01-31
20  49463    TZ-2014-8190 2014-12-05")
#> Warning: Missing column names filled in: 'X1' [1]

modifier <- function(input.data, cut.points = NULL) {
    if (length(cut.points) == 2) {
        date_col <- colnames(input.data)[sapply(input.data, is.Date)]
        filtered.data <- input.data %>%
            rename(Date = !! date_col) %>%
            filter(Date %within% interval(cut.points[1], cut.points[2])) %>%
            rename_with(~ date_col, Date)
        return(filtered.data)
    } else {
        input.data
    }
}
modifier(ex_data, cut.points = c("2012-01-01", "2013-01-01"))
#> # A tibble: 5 x 4
#>      X1 Row.ID Order.ID       Order.Date
#>   <dbl>  <dbl> <chr>          <date>    
#> 1     1  32298 CA-2012-124891 2012-07-31
#> 2     8  31192 IN-2012-86369  2012-04-14
#> 3    10  40936 CA-2012-116638 2012-01-28
#> 4    12  28879 ID-2012-28402  2012-04-19
#> 5    14   4132 MX-2012-130015 2012-11-13

【讨论】:

    猜你喜欢
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多