我尝试在此数据集中将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)
答案 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 = id
或ids == id
。
如果您有兴趣,语法为x[i, on=, j, by=.EACHI]
,其中x
和i
为表格。对于i
的每一行,我们会根据x
条件查找on=
行(左侧是x
中的列;右侧是列中的列i
);然后我们为每个j
&#34;每行i
&#34; by=.EACHI
)j = .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$date
或df$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))
)