groupby总结在groupby dplyr之外

时间:2018-05-02 16:42:02

标签: r dplyr

我尝试在此数据集中将ID与日期分组,但我想根据该组之外的某个功能进行汇总。

library(dplyr)
library(lubridate)

set.seed(100)
df <- data.frame(ids = sample(c('436247', '2465347', '346654645'), 10000, replace=TRUE),
                 date = sample(seq.Date(ymd('2018-03-01'), ymd('2018-05-01'), by=1), 10000, replace=TRUE))

new_df <- df %>%
    group_by(ids, date) %>%
    summarise(events = length(ids[date >= date - 30 & date <= date]))

我试图接受这个数据框并回答问题 - &#34;对于每个ID,每个日期,该ID中有多少其他记录都在该日期的过去30天内#&# 34 ;.不幸的是,当我group_by ID和日期时,它只会在分组日期内查找。我已经在下面创建了解决方案,但不确定dplyr是否有更好的解决方案?

groupby_function <- function(df, spec_date){
  result <- df %>%
      group_by(ids) %>%
      summarise(events = length(ids[date >= spec_date - 30 & date <= spec_date])) %>%
      mutate(date = spec_date)
  return(result)

} 

date_vector <- seq.Date(ymd('2018-03-01'), ymd('2018-05-01'), by=1)
list_results <- lapply(date_vector, groupby_function, df=df)
x <- do.call(rbind, list_results)

4 个答案:

答案 0 :(得分:1)

  

&#34;对于每个ID,每个日期,该ID中有多少其他记录都在该日期的过去30天内#34;

为此,&#34;加入&#34;条件有道理,但isn't yet included in dplyr。在此之前,您可以在dplyr链中使用data.table:

# enumerate id-date combos of interest
grid_df = expand.grid(
  id = unique(df$ids), 
  d = seq(min(df$date), max(df$date), by="day")
)

# helper function
library(data.table)
count_matches = function(DF, targetDF, ...){
  onexpr = substitute(list(...))
  data.table(targetDF)[DF, on=eval(onexpr), .N, by=.EACHI]$N
}

# use a non-equi join to count matching rows
res = grid_df %>% 
  mutate(d_dn = d - 30) %>% 
  mutate(n = count_matches(., df, ids = id, date >= d_dn, date <= d)) %>% 
  as.tibble

# A tibble: 186 x 4
          id          d       d_dn     n
      <fctr>     <date>     <date> <int>
 1    436247 2018-03-01 2018-01-30    72
 2   2465347 2018-03-01 2018-01-30    69
 3 346654645 2018-03-01 2018-01-30    51
 4    436247 2018-03-02 2018-01-31   123
 5   2465347 2018-03-02 2018-01-31   120
 6 346654645 2018-03-02 2018-01-31   100
 7    436247 2018-03-03 2018-02-01   170
 8   2465347 2018-03-03 2018-02-01   166
 9 346654645 2018-03-03 2018-02-01   154
10    436247 2018-03-04 2018-02-02   228
# ... with 176 more rows

我认为它应该适用于平等条件来编写ids = idids == id

如果您有兴趣,语法为x[i, on=, j, by=.EACHI],其中xi为表格。对于i的每一行,我们会根据x条件查找on=行(左侧是x中的列;右侧是列中的列i);然后我们为每个j&#34;每行i&#34; by=.EACHIj = .N。在这种情况下,x表示我们会计算匹配的N行,并将其作为一列计数protected void Application_Start(){ //other code DisplayModeProvider.Instance.Modes.Insert(0,new DefaultDisplayMode("IE9") { ContextCondition=context=> context.request.UserAgent.Contains("MSIE 9") }); } 返回。

答案 1 :(得分:0)

你可以看看&#34;未组合的&#34;数据只需返回原始数据框(调用df$datedf$ids)。所以我认为你所追求的是什么

test_df <- df %>%
  group_by(ids, date) %>%
  summarise(events = length(df$ids[df$date >= date[1] - 30 & df$date <= date[1] & df$ids == ids[1]]))

此外,我运行了您提议的功能,但我没有看到原始group_by解决方案的结果有任何差异,因此我认为这不是您想要的。

答案 2 :(得分:0)

如果'非dplyr'解决方案可以接受,那么这可以为您提供所需的解决方案。

MyProgram

P[1,6]
c1  c2  c3  c4  c5  c6
r1   0   0   0   0   0   0
type mismatch
r(109);

或者,在df$diff <- as.vector( sapply(unique(df$ids), function(x) sapply(df$date[df$ids == x], function(y) sum(abs(y - df$date[df$ids == x]) >= 30) ) ) ) 中,您可以使用以下方式获得上述结果:

dplyr

答案 3 :(得分:0)

这是一个答案。但它假设每个id都有连续的日期序列。

df %>%
  group_by(ids, date) %>%
  count() %>%
  arrange(ids, date) %>%
  group_by(ids) %>%
  mutate(
    events = cumsum(n) - cumsum(lag(n, 30, 0))
  )