首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >groupby摘要在groupby dplyr之外

groupby摘要在groupby dplyr之外
EN

Stack Overflow用户
提问于 2018-05-03 00:42:02
回答 4查看 220关注 0票数 2

我尝试在此数据集中使用日期对ids进行分组,但我想根据组外的一个特征进行总结。

代码语言:javascript
复制
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]))

我正在尝试获取这个数据帧并回答这个问题-“对于每个id,每个日期,在该日期的过去30天内,该id中有多少其他记录”。不幸的是,当我同时group_by I和date时,它只在分组的日期内显示。我已经创建了下面的解决方案,但不确定是否有更好的dplyr解决方案?

代码语言:javascript
复制
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)
EN

回答 4

Stack Overflow用户

发布于 2018-05-03 01:30:32

“对于每个id和每个日期,该id中有多少其他记录在该日期的过去30天内”

因此,"join by“条件是有意义的,但是isn't yet included in dplyr。在此之前,您可以在dplyr链中使用data.table:

代码语言:javascript
复制
# 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的每一行,我们根据on=条件查找x的行(左边指的是x中的列,右边指的是i中的列);然后,我们对每个行执行j ("by each row of i“,所以是by=.EACHI)。在本例中,j = .N意味着我们对匹配的x行进行计数,这些行以N计数列的形式返回。

票数 1
EN

Stack Overflow用户

发布于 2018-05-03 00:58:56

只需返回到原始数据框(调用df$datedf$ids),就可以查看“未分组”的数据。所以我认为你想要的是

代码语言:javascript
复制
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解决方案的结果有任何不同,所以我认为这不是您想要的。

票数 0
EN

Stack Overflow用户

发布于 2018-05-03 01:32:43

如果一个'non dplyr‘解决方案是可接受的,这将给你你想要的。

代码语言:javascript
复制
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中,您可以使用以下命令获得类似上面的结果:

代码语言:javascript
复制
f <- function(x) {
  sapply(x, function(y) sum(abs(y - x) >= 30))
  }

df$diff <- unlist(
  df %>%
    group_by(ids) %>%
    do(diff = f(.$date)) %>%
    .$diff
  )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50139612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档