Max Mustermann
Max Mustermann

Reputation: 191

Make a Consecutive row calculation in R

Suppose I have the following data:

a<- c(1:10)
b<- c(10:1)

Now I want to make a Consecutive calculation (of variable length in this example 2)on both rows (a and b) and save the output in two separate lists(a and b).

The calculation should look like the following:

for a:

(1+2)/2; (2+3)/2; (3+4)/2;...; (9+10)/2

for b(the same):

(10+9)/2; (9+8)/2; (8+7)/2;...;(2+1)/2

a
1,5 2,5 3,5 ... 9,5
b
9,5 8,5 7,5 ... 1,5

I found this function in StackOverflow:

v <- c(1, 2, 3, 10, 20, 30)
grp <- 3

res <- sapply(1:(length(v)-grp+1),function(x){sum(v[x:(x+grp-1)])})

Which pretty much does what i need but I would prefer a function which does that without using sapply and just base R. Any Help would be appreciated!

Upvotes: 0

Views: 230

Answers (4)

RHertel
RHertel

Reputation: 23788

You could try this:

d1 <- ((a + a[seq(a)+1])/2)[-length(a)]
#[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5

and

d2 <- ((b + b[seq(b)+1])/2)[-length(b)]
#[1] 9.5 8.5 7.5 6.5 5.5 4.5 3.5 2.5 1.5

The last part [-length(a)] and [-length(b)] removes NA entries at the end of the sequence.

Upvotes: 1

jogo
jogo

Reputation: 12559

na.omit(filter(a, c(1,1))/2)
na.omit(filter(b, c(1,1))/2)

Upvotes: 3

Colonel Beauvel
Colonel Beauvel

Reputation: 31161

You can do base R:

f = function(x) (head(x,-1) + tail(x,-1))/2

list(a=f(a), b=f(b))
#$a
#[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5

#$b
#[1] 9.5 8.5 7.5 6.5 5.5 4.5 3.5 2.5 1.5

Or if you want to use the apply family:

library(zoo)

list(a=rollapply(a,2, mean), b=rollapply(b,2, mean))

sapply is really not recommended but if you want to use it (just for test!):

sapply(1:(length(a)-1), function(i) mean(a[i:(i+1)]))
#[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
#same for b

Upvotes: 5

Ronak Shah
Ronak Shah

Reputation: 388817

If the length of a and b is same

for(i in 1:(length(a) - 1))
{
 list1[i] <- (a[i] + a[i+1])/2
 list2[i] <- (b[i] + b[i+1])/2
}
> list1
#[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5

> list2
#[1] 9.5 8.5 7.5 6.5 5.5 4.5 3.5 2.5 1.5

Or else write two different loops for both

for(i in 1:(length(a) - 1))
{
  list1[i] <- ((a[i] + a[i+1])/2)
}

for(i in 1:(length(b) - 1))
{
  list2[i] <- ((b[i] + b[i+1])/2)
}

Upvotes: 0

Related Questions