我正在尝试创建一个函数,该函数将最接近的n值与给定日期相加。因此,如果我有5周的数据,并且n = 2,则第1周的值将是第2周和第3周的总和,第2周的值将是第1周和第3周的总和等。示例:
library(dplyr)
library(data.table)
Week <- 1:5
Sales <- c(1, 3, 5, 7, 9)
frame <- data.table(Week, Sales)
frame
Week Sales Recent
1: 1 1 8
2: 2 3 6
3: 3 5 10
4: 4 7 14
5: 5 9 12
我想为我做一个函数,为最近的n(不仅仅是2)提供输入,但是现在我想要2对。这是我使用lag / lead的函数:
RecentSum = function(Variable, Lags){
Sum = 0
for(i in 1:(Lags/2)){ #Lags/2 because I want half values before and half after
#Check to see if you can go backwards. If not, go foward (i.e. use lead).
if(is.na(lag(Variable, i))){
LoopSum = lead(Variable, i)
}
else{
LoopSum = lag(Variable, i)
}
Sum = Sum + LoopSum
}
for(i in 1:(Lags/2)){
if(is.na(lead(Variable, i))){ #Check to see if you can go forward. If not, go backwards (i.e. use lag).
LoopSum = lag(Variable, i)
}
else{
LoopSum = lead(Variable, i)
}
Sum = Sum + LoopSum
}
Sum
}
当我RecentSum(frame$Sale,2)
时,由于多种原因,我认为[1] 6 10 14 18 NA
出错了:
if
语句仅在第一周播出,因此延迟始终为NA,并且始终为非NA。6
而不是8
,因为第一个for循环将它发送到lead(_,1),但是第二个for循环执行相同的操作。我想不出如何让我的第二个for-loop认识到这一点。是否有功能或库(Zoo
?)使这项任务变得简单?我想让自己的功能为了练习/理解而工作,但在这一点上我宁愿完成它。
谢谢!
答案 0 :(得分:4)
要详细说明我的评论,lead
和lag
是要在dplyr
等矢量化函数中使用的函数。这是一种在dplyr
内不使用函数的方法:
df <- tibble(week = Week, sales = Sales)
df %>%
mutate(recent = case_when(is.na(lag(sales)) ~ lead(sales, n = 1) + lead(sales, n = 2),
is.na(lead(sales)) ~ lag(sales, n = 1) + lag(sales, n = 2),
TRUE ~ lag(sales) + lead(sales)))
这给你这个:
# A tibble: 5 x 3
week sales recent
<int> <dbl> <dbl>
1 1 1 8
2 2 3 6
3 3 5 10
4 4 7 14
5 5 9 12
答案 1 :(得分:1)
1)假设k甚至将to
定义为索引的向量,使得对于to
的每个元素,我们将{{1}的k + 1个元素相加在那个索引中结束并从中减去Sales
:
Sales
,并提供:
k <- 2 # number of elements to sum
n <- nrow(frame)
to <- pmax(k+1, pmin(1:n + k/2, n))
Sum <- function(to, Sales) sum(Sales[seq(to = to, length = k+1)])
frame %>% mutate(recent = sapply(to, Sum, Sales) - Sales)
请注意,通过使用以下行替换上面的最后一行代码,解决方案可以完全在基础R中完成:
Week Sales recent
1 1 1 8
2 2 3 6
3 3 5 10
4 4 7 14
5 5 9 12
2)这将连接Sales系列之前和之后的相应元素,以便普通滚动总和给出结果。
transform(frame, recent = sapply(to, Sum, Sales) - Sales)
请注意,如果k = 2,则将其减少到这个单行:
library(zoo)
ix <- c(seq(to = k+1, length = k/2), 1:n, seq(to = n-k, length = k/2))
frame %>% mutate(recent = rollsum(Sales[ix], k+1) - Sales)
,并提供:
frame %>% mutate(recent = rollsum(Sales[c(3, 1:n(), n()-2)], 3) - Sales)
更新:已修复为k&gt; 2