I'm a R newbie. I've got a vector
vec <- c(105,29,41,70,77,0,56,49,63,0,105)
and i would like to sum values till "0" occurs and then create a vector with such values, such as:
vec2 <- c(322,168,105)
But i really don't know where to start! Any suggestion?
The
aggregate
function is useful for this kind of thing. You create a grouping variable withcumsum
(similar to how @Spacedman explained). Using thesum
function as the aggregating operation. The[[2]]
at the end just extracts what you want from whataggregate
returns:rowsum()
is known to be quite fast. We can usecumsum(vec == 0)
for the grouping.Another option is
by
Benchmark
Benchmark comparison of the methods for a larger vector based on
microbenchmark
Starting with this vector...
We can compute a logical TRUE/FALSE vector of where the zeroes are:
When you add FALSE and TRUE, FALSE is zero and TRUE is one, so if we add that vector up every time we get to a TRUE the value increases. So using
cumsum
for the cumulative sum, we get:Now that result defines the groups that we want to add up within, so let's
split
vec
by that result:So apart from the zeroes in the second and subsequent parts of the list, that's the numbers we want to add up. Because we are adding we can add the zeroes and it doesn't make any difference (but if you wanted the mean you would have to drop the zeroes). Now we use
sapply
to iterate over list elements and compute the sum:Job done. Ignore the
0 1 2
labels.With vapply
Here is an option with
vapply
With Reduce
Here is a solution using
Reduce
With A Loop
Or maybe an old fashioned loop
Benchmarking
Data
Here is the data used for benchmarking
Functions
Here are the functions for the second benchmarking figures:
Benchmarking
Here are the two benchmarking processes combined:
Results
Here are the benchmarking results