我尝试在此数据集中使用日期对ids进行分组,但我想根据组外的一个特征进行总结。
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解决方案?
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)发布于 2018-05-03 01:30:32
“对于每个id和每个日期,该id中有多少其他记录在该日期的过去30天内”
因此,"join by“条件是有意义的,但是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的每一行,我们根据on=条件查找x的行(左边指的是x中的列,右边指的是i中的列);然后,我们对每个行执行j ("by each row of i“,所以是by=.EACHI)。在本例中,j = .N意味着我们对匹配的x行进行计数,这些行以N计数列的形式返回。
发布于 2018-05-03 00:58:56
只需返回到原始数据框(调用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解决方案的结果有任何不同,所以我认为这不是您想要的。
发布于 2018-05-03 01:32:43
如果一个'non dplyr‘解决方案是可接受的,这将给你你想要的。
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中,您可以使用以下命令获得类似上面的结果:
f <- function(x) {
sapply(x, function(y) sum(abs(y - x) >= 30))
}
df$diff <- unlist(
df %>%
group_by(ids) %>%
do(diff = f(.$date)) %>%
.$diff
)https://stackoverflow.com/questions/50139612
复制相似问题