如何跨数据框中的多个变量执行R等效的Excel的COUNTIFS函数

时间:2017-12-22 04:39:11

标签: r

我正在处理一个项目,并尝试创建一个我们在任何给定日期的开放案例数量的图表。数据表的一个例子如下。

    case_files <- tibble(case_id = 1:10,
                         date_opened = c("2017-1-1",
                                         "2017-1-1",
                                         "2017-3-4",
                                         "2017-4-4",
                                         "2017-5-5",
                                         "2017-5-6",
                                         "2017-6-7",
                                         "2017-6-6",
                                         "2017-7-8",
                                         "2017-7-8"),
                         date_closed = c("2017-4-1",
                                         "2017-4-1",
                                         "2017-5-4",
                                         "2017-7-4",
                                         "2017-7-5",
                                         "2017-7-6",
                                         "2017-8-7",
                                         "2017-8-6",
                                         "2017-9-8",
                                         "2017-10-8"))
    case_files$date_opened <- as.Date(case_files$date_opened)              
    case_files$date_closed <- as.Date(case_files$date_closed)

我要做的是创建另一个数据框,其中包含过去一年的日期和被考虑的案例数量#34; Open&#34;在每个日期。然后我就可以从这个数据框中进行绘图。

    daily_open_cases <- tibble(n = 0:365,
                               date = today() - n,
                               qty_open = .....)

date_opened之后或date_closed之前或之前的案件被视为开放日期

我考虑过进行条件子集化,然后使用nrow(),但似乎无法让它发挥作用。必须有一种更简单的方法来做到这一点。我可以使用COUNTIFS函数在Excel中轻松完成此操作。

谢谢!

2 个答案:

答案 0 :(得分:2)

Excel功能基本上是逻辑1和0的总和。使用sum函数在R中很容易做到。我构建了一个具有所有日期的结构,然后在case_files结构中所有成对行中使用下面的两个不等式总结逻辑向量。 R中的& - 函数是矢量化的:

daily_open_cases <- tibble(dt = as.Date("2017-01-01")+0:365,
                                   qty_open = NA)
daily_open_cases$qty_open = sapply(daily_open_cases$dt, 
       function(d) sum(case_files$date_opened <= d & case_files$date_closed >=d) )


> head( daily_open_cases)
# A tibble: 6 x 2
          dt qty_open
      <date>    <int>
1 2017-01-01        2
2 2017-01-02        2
3 2017-01-03        2
4 2017-01-04        2
5 2017-01-05        2
6 2017-01-06        2
> 

答案 1 :(得分:0)

这里是一个整齐的过渡&#39;解决方案,该方法与42我刚刚使用dplyr s group_bymutate而不是base-r sapply的方法相同。

library(tidyverse)
library(magrittr)

days_files <- tibble(
  date = as.Date("2017-01-01")+0:365,
  no_open = NA_integer_
)

days_files %<>% 
  group_by(date) %>%
  mutate(
    no_open = sum(case_files$date_opened <= date & case_files$date_closed >= date)
  )

    # A tibble: 366 x 2
# Groups:   date [366]
         date no_open
       <date>   <int>
 1 2017-01-01       2
 2 2017-01-02       2
 3 2017-01-03       2
 4 2017-01-04       2
 5 2017-01-05       2
 6 2017-01-06       2
 7 2017-01-07       2
 8 2017-01-08       2
 9 2017-01-09       2
10 2017-01-10       2
# ... with 356 more rows