我正在尝试在数据集上重复使用Excel中的AVERAGEIFS函数所做的事情:
EG_df <- data.frame(id = c("red_blue", "white_blue", "red_yellow","white_yellow", "brown_blue", "brown_yellow"),
StartDate = as.Date(c('2019-1-1','2019-3-1','2019-7-1','2018-1-1','2018-3-1','2018-7-1')),
EndDate = as.Date(c('2019-6-1','2019-12-1','2019-8-1','2018-1-1','2018-3-1','2018-7-1')),
avg_Value = NA
)
source <- data.frame(source.id = c("red_blue", "red_blue", "red_blue","brown_yellow", "brown_yellow", "brown_yellow"),
source.Date = as.Date(c('2019-1-1','2019-2-1','2019-3-1','2018-7-1','2018-8-1','2018-9-1')),
source.Value = c(22,56,32,31,14,7)
)
我需要填写的逻辑 EG.df$avg_Value
:
对于{strong> EG_df
中的每一行,当source.value
在source.Date
和StartDate
之间时,返回EndDate
的平均值。
用于澄清的Excel公式:
= AVERAGEIFS(source.value,source.id,id,source.Date,“> =”&StartDate,source.Date,“> =”&EndDate)
任何帮助将不胜感激!
答案 0 :(得分:1)
使用非等额联接可以非常有效地做到这一点:
library(data.table)
setDT(source); setDT(EG_df)
EG_df[, avg_Value :=
source[copy(.SD), on=.(source.id = id, source.Date >= StartDate, source.Date <= EndDate), mean(x.source.Value), by=.EACHI]$V1
]
id StartDate EndDate avg_Value
1: red_blue 2019-01-01 2019-06-01 36.66667
2: white_blue 2019-03-01 2019-12-01 NA
3: red_yellow 2019-07-01 2019-08-01 NA
4: white_yellow 2018-01-01 2018-01-01 NA
5: brown_blue 2018-03-01 2018-03-01 NA
6: brown_yellow 2018-07-01 2018-07-01 31.00000
(由于我仅使用提供的摘录source
而不是完整表格,所以存在NAs。)
工作原理
使用x[i, j]
的{{1}}子集,然后求值i
,其中j
引用.SD
ata的S
ubset。< / p>
当D
和x
都是表时,i
是一个联接,其中x[i, on=, j, by=.EACHI]
指定联接条件,并且on=
对表的每一行进行评估j
。
由于i
返回了一个未命名的列,因此它的默认名称为j = mean(x.source.Value)
。
在V1
的{{1}}内,j
通过向其分配x[i, j]
来创建或修改列v := val
。
答案 1 :(得分:1)
使用dplyr天秤座
library(dyplr)
df = EG_df %>%
left_join(source, by = c('id' = 'source.id')) %>%
filter((StartDate <= source.Date) & (source.Date <= EndDate)) %>%
group_by(id, StartDate, EndDate) %>%
summarise(value = mean(source.Value))
答案 2 :(得分:0)
使用tidyverse
dplyr::inner_join(source,EG_df,by = c("source.id"="id")) %>%
dplyr::filter(source.Date >= StartDate,
source.Date <= EndDate) %>%
dplyr::group_by(source.id,StartDate,EndDate) %>%
dplyr::summarise(avg_Value = mean(source.Value))
答案 3 :(得分:0)
考虑运行base
的{{1}}程序包,以获取ID组和日期范围的平均值。然后merge > subset > aggregate
将该结果集返回到原始数据集。
merge
在旁边-这类似于SQL的greatest-n-per-group问题(正式的StackOverflow标记),在该问题中, agg_df 是子查询或连接到原始表的CTE。