I have data frame in R that looks like this :
a | b |
---|---|
8 | -16 |
19 | -26 |
30 | -36 |
41 | -46 |
52 | -56 |
I want to slide it or rollapply it with width 3 in both columns and calculate the the sum of the two minimum.
BUT.!!!!
I want progressively go tho width 3 starting with width (3 1)/2 = 2 and then go to width 3.
In my example must start with the first 2 rows:
a | b |
---|---|
8 | -16 |
19 | -26 |
result must be the sum of the minimums of columns a and b 8 (-26)=-18 next
a | b |
---|---|
8 | -16 |
19 | -26 |
30 | -36 |
result must be the sum of the minimums of columns a and b 8 (-36)=-28
next
a | b |
---|---|
19 | -26 |
30 | -36 |
41 | -46 |
19-46 = -27
next
a | b |
---|---|
30 | -36 |
41 | -46 |
52 | -56 |
30-56 = -26
and last
a | b |
---|---|
41 | -46 |
52 | -56 |
41-56=-15.
The width must be 2,3,3,3,2.
In general if this data frame had 100 rows with window 13 it will start from top to bottom with window (or width) (13 1)/2 = 7, then it will continue to 8,9,10,12,13,13,...,13,12,11,10,9,8,7.
How can I do this in R ?
library(tidyverse)
a = c(800,1900,3000,4100,5200)
b = c(-1600,-2600,-3600,-4600,-5600)
w = tibble(a,b)
CodePudding user response:
We may use rollapply
from zoo
with partial = TRUE
to loop over the sequence of rows, subset the data based on the index, get the min
from columns (sapply(..., min)
) and get the sum
of those
library(zoo)
wd <- 3
rollapply(seq_len(nrow(df1)), FUN = function(i) sum(sapply(df1[i,],
min)), width = wd, partial = TRUE)
[1] -18 -28 -27 -26 -15
data
df1 <- structure(list(a = c(8L, 19L, 30L, 41L, 52L), b = c(-16L, -26L,
-36L, -46L, -56L)), class = "data.frame", row.names = c(NA, -5L
))
CodePudding user response:
in Base R you could do:
fn <- function(x, window){
na <- rep(NA, ceiling((window-1)/2))
apply(embed(c(na, x, na), window),1, min, na.rm = TRUE)
}
rowSums(sapply(df,fn, 3))
[1] -18 -28 -27 -26 -15