Reputation: 191
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
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
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
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